参考:Go 切片:用法和实质
在Go中,切片的实质是一个构造体,蕴含一个指向底层数组的指针(prt),长度(len),容量(cap)。所以,切片自身蕴含一个指针,将切片按值传递给函数,在函数内对其批改,影响将会传递到函数外。因为底层的数组被批改了。
但当对切片进行append()
操作,若是元素数量超过原有切片的容量,将会使得切片容量增大,这就是问题所在。扩容后的切片,实质上是产生一个新的底层数组。如果在函数内对切片增加元素导致扩容,会导致元素内的切片指向一个新的数组,然而函数外的切片依然指向原来旧的数组,则将会导致影响无奈传递到函数外。如果心愿函数内对切片扩容作用于函数外,就须要以指针模式传递切片。
上面的代码展现了,在change2()
外部对切片扩容,导致其指向新的数组,(能够看到切片首个元素地址变了),然而无奈影响内部的切片。
package mainimport "fmt"func change1(result []int){ fmt.Printf("外部1 %p%v len:%d cap:%d\n",result,result,len(result),cap(result)) result[0]=9}func change2(result []int){ result=append(result,92) fmt.Printf("外部2 %p%v len:%d cap:%d\n",result,result,len(result),cap(result))}func change3(result *[]int){ *result=append(*result,92) fmt.Printf("外部3 %p%v len:%d cap:%d\n",*result,*result,len(*result),cap(*result))}func main(){ result:=make([]int,1) fmt.Printf("内部 %p%v len:%d cap:%d\n",result,result,len(result),cap(result)) change1(result) fmt.Printf("内部 %p%v len:%d cap:%d\n",result,result,len(result),cap(result)) change2(result) fmt.Printf("内部 %p%v len:%d cap:%d\n",result,result,len(result),cap(result)) change3(&result) fmt.Printf("内部 %p%v len:%d cap:%d\n",result,result,len(result),cap(result))}
输入
内部 0xc000018100[0] len:1 cap:1外部1 0xc000018100[0] len:1 cap:1内部 0xc000018100[9] len:1 cap:1外部2 0xc000018130[9 92] len:2 cap:2内部 0xc000018100[9] len:1 cap:1外部3 0xc000018150[9 92] len:2 cap:2内部 0xc000018150[9 92] len:2 cap:2