别再说传引用
还是传值
了,在 Golang 里面应该先搞清楚这个东西的类型是什么。
专栏的介绍可以参考 《GotchaGolang专栏》,代码可以看《宝库-Gotcha》。
透过现象看本质。我们当初在 C/C++ 中折腾指针啊,引用啊,不就是为了能否修改原来的变量么?
Golang 直接指针问题的核心,用类型本身的性质解决了该问题;而不是过多的把注意力放在参数传递上。
- 值类型? — 包括基本类型,数组,自定义类型struct, 只有传递指针才能更改其原来内存的内容,否则值传递只能是拷贝
- 引用类型? — 包括 slice, map, chan, func,这里本身就是引用类型, 即便是值传递也可以更改原来的内容(但是内部和外部的地址不同)
举个例子吧: 自定义的 type, struct
1 | func (u user) fun1() { |
Value receiver操作的是值的拷贝,而pointer receiver操作的是实际的值。
用pointer去调用value receiver的方法,实际的操作是: (*p).fun1()
而用value去调用pointer receiver的方法,实际的操作是:(&v).fun2()
对于引用类型,就不要,也不需要去使用其指针了,直接拿到实例就可以了,一般是 make
返回的,内部实现返回的其实是指针。
1 |
|
搞清楚是引用类型,还是值类型;再决定是传递指针,还是传递引用
因为可以看到引用类型本身相关的方法已经做了封装,不需要再额外传递指针了。
但是不管哪种类型,只要是值传递,那么调用内部和外部,相关参数的地址肯定不一样,值传递就是拷贝啊,都是副本(即便是引用类型,也是副本;可以比较内外引用变量的地址)。但是决定能够修改原来的变量与否,还在于传递的变量本身是值类型,还是引用类型。
透过现象看本质。我们当初在 C/C++ 中折腾指针啊,引用啊,不就是为了能否修改原来的变量么
?
Golang 直指指针问题的核心,用类型本身的性质解决了该问题;而不是过多的把注意力放在参数传递上。
Merlin 2018.3 参数本身的坑,核心且关键