在最近的学习和实践中,照着别人的代码敲,仅仅只是把别人写在方法内的片段直接拿出来用,结果却出人意料,所以很纳闷!
示例代码:
1 | func CryptBlocks(dst, src []byte) { |
这个分块处理切片数据的方法很巧妙,我第一次看见的时候(认定切片是传引用),认为这个方法错了,最终dst变成了空切片。
先看一个Slice的例子:
1 | package main |
输出:
1 | Slice: [0 1 2 3 4 5] |
我们会发现,在方法changeSlice中对形参的修改即真实修改。如果这时我们将其定性为引用传值,为之过早!
我们将代码稍微修改一下:
1 | package main |
输出:
1 | SliceAddr: 0xc82000e0a0 , Slice: [0 1 2 3 4 5] |
由此可见,在方法内的那个s(地址:0xc8200460c0)并非传入的那个slice(地址:0xc82000e0a0),但是为什么它的修改能影响到原来的数据呢?
原因是Golang中的Slice类型在创建的时候,可以理解为:创建一个新的变量,存储数组中的一个片段的数据,虽然自己是一个新的变量,有自己的内存地址,但是内部的数据确实共享的以前的底层数据。
我们在做一个尝试:
1 | package main |
输出:
1 | Slice addr: 0xc82000e0a0 |
可以看出,切片内部存储是内容其实是同一块内存,被共享的数据,而切片自己却拥有自己的地址。
所以说,Golang的基本类型都是传值,还是没错的。
参考内容