go值传递
什么是值传递、传地址、传引用
任何一门语言在函数调用的时候,都有传参数的情况。都涉及传的是值,还是引用,或是指针。
传值 其实就是实参拷贝传递给形参。简单来说就是把实参赋值给形参,赋值完毕后实参和形参就没有任何的关系了,对形参的修改不会影响到实参。
传地址 传地址其实也是一种值传递,为什么这么说呢?因为传地址其实是把实参地址的拷贝传递给形参。简单来说,传地址就是把实参的地址复制给形参。复制完毕后实参的地址和形参的地址没有任何关系,对形参址址的更改不会影响到实参,但是对形参址址所指向的对象的更改却直接反应在实参中,因为形参指向的对象就是形参的对象。
传引用 传引用本质没有任何实参的拷贝,简单来说,就是让另一个变量也执行该实参。就是两个变量指向同一个对象。这是对形参的修改,必然反映到实参上。
golang 来说是没有引用传递的,采用的是值传递,即使是指针,也是将指针的地址即指针的指针,拷贝一份传递。
Slice 类型陷井
golang 提供了 array 和 slice 两种序列结构。array 是值类型。slice 则是复合类型,slice 是基于 array 实现的。 当函数传 slice 的时候是值传递,通过原始变量进行切片传入。因为共同指向了 array,所以 函数内对 slice 进行修改可能也会对函数外的 array,slice 有影响。情况如下
当在函数内执行 append 操作时,如果超过 slice 的容量,即数组的越界的时候,需要通过动态规划的方式创建了个新的数组块。把原有数据复制到新的数组,这个新的 array 则为 slice 新的底层依赖。
当在函数执行任何操作时,没有超过 slice 容量,对 slice 的数据更新则会传递到函数外层。
当然如果传递的是指针,肯定也是会传递到函数外层的。
map 传参
make 函数返回的是一个 hmap 类型的指针 *hmap,所以传 map 可以直接修改其值。
chan 传参
chan 类型本质上和 map 类型是一个的,make 返回的是一个 *hchan 指针类型。
总节
golang 中所有的传参都是值传递(传值),都是一个副本,一个拷贝。非引用类型 int、string、struct 等,这样就在函数中无法修改原内容数据。引用类型 指针、map、slice、chan 等,这样就可以修改原内容数据。
是否可以修改原内容数据,和传值、传引用没有必然的关系。在C++中,传引用肯定是可以修改原内容数据的,在Go语言里,虽然只有传值,但是我们也可以修改原内容数据,因为参数是引用类型。
这里也要记住,引用类型和传引用是两个概念。
再记住,Go里只有传值(值传递)
参考
Last updated
Was this helpful?