Golang的Slice的坑
作者:互联网
数据的引用传递还是值传递
Go类型:基本类型(bool string int array)、引用类型(切片\map\interface\func\channel)、 结构类型、 自定义类型
引用类型,标头值里包含一个指 针,指向底层的数据结构,当我们在函数中传递引用类型时,其实传递的是这个标头值的副本,它所指向的底层结构并没有被复制传递,这也是引用类型传递高效的原因。
比如切片(引用类型)和数组(基本类型)
看下切片原理,可以知道切片其实内部是一个unsafearray ,非线程安全数组的指针;
也就是说:
func TestSliceTrans(t *testing.T) { var p = []string{"a"} fmt.Printf("TestSliceTrans %p %s \n", &p, p) S(p) fmt.Printf("TestSliceTrans %p %s \n", &p, p) } func S(l []string) { l[0] = "b" fmt.Printf("S %p %s \n", &l, l) }
输出
TestSliceTrans 0xc0000be180 [a] S 0xc0000be1b0 [b] TestSliceTrans 0xc0000be180 [b]
即使 S 函数里面的 l 的指针和 上层不一致,但是这个切片指向的内部的数组是同一个,所以 S 函数内更改了切片的值
func P(p Person) { p.Name = "rose" fmt.Printf("P %p\n", &p) } func TestSliceTrans(t *testing.T) { var p = []string{"a"} fmt.Printf("TestSliceTrans %p %s \n", &p, p) S(p) fmt.Printf("TestSliceTrans %p %s \n", &p, p) } func S(l []string) { l = append(l, "b") fmt.Printf("S %p %s \n", &l, l) }
输出
TestSliceTrans 0xc00000e198 [a] S 0xc00000e1c8 [a b] TestSliceTrans 0xc00000e198 [a]
为什么这里的切片值没有被改变呢?
这里就涉及切片的append的时候的扩容方式,在append的时候切片会将底层指向的数组更换为新的数组,也就是说 append之后对之前的底层指向的数组是没有做操作的,所以不会改变值
参考地址:
https://blog.csdn.net/weixin_52690231/article/details/123967274#11_5
TRANSLATE with x English TRANSLATE with COPY THE URL BELOW Back EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back标签:切片,Slice,string,fmt,Golang,func,Printf,TestSliceTrans 来源: https://www.cnblogs.com/xuweiqiang/p/16389752.html