每日一招之golang的append
请说出一下打印结果
第一种
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package main
import "fmt"
func main() {
sli := make([]int, 2, 3)
sli[0] = 0
sli[1] = 1
res := changeSlice(sli)
fmt.Printf("sli: %+v, res: %+v \n", sli, res)
res[0] = 100
fmt.Printf("sli: %+v, res: %+v \n", sli, res)
}
func changeSlice(s []int) []int {
s = append(s, 3)
return s
}结果:
1
2
3☁ test2 go run main.go
sli: [0 1], res: [0 1 3]
sli: [100 1], res: [100 1 3]- 当sli传递给函数的时候,新建了切片s。在函数中给s进行了append一个元素,由于此时s的容量足够到,并没有生成新的底层数组。当修改返回的res的时候,res与sli共用了底层的数组,因此修改ret的原始,相应的也看到了slice的改变。
第二种
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package main
import "fmt"
func main() {
sli := make([]int, 2, 2)
sli[0] = 0
sli[1] = 1
res := changeSlice(sli)
fmt.Printf("sli: %+v, res: %+v \n", sli, res)
res[0] = 100
fmt.Printf("sli: %+v, res: %+v \n", sli, res)
}
func changeSlice(s []int) []int {
s = append(s, 3)
return s
}结果:
1
2
3
4
5☁ test2 go run main.go
sli: [0 1], res: [0 1 3]
sli: [0 1], res: [100 1 3]- 函数中先改变s第一个元素的值,由于slice和s都共用了底层数组,因此无论原始切片slice还是ret,第一个元素都是-1.然后append操作之后,因为超出了s的容量,因此会新建底层数组,虽然s变量没变,但是他的底层数组变了,此时修改s第一个元素,并不会影响原始的slice切片。
总结
切片底层本质是基于数组
append的是用来向切片添加数据的,当前切片容量够的时候,append生成的心切片依然和之前的切片共享底层数组,一旦当前切片的容量不够用的时候就会另起灶炉,生成新的底层数组。