golang中对“引用传递”的误解
source link: https://segmentfault.com/a/1190000040213952
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
最近看很多教程或者说博客上都说 golang 中的 slice、map、channel、func
都是“引用传递”
,然而一方面又说 golang 中所有类型都是值传递,总感觉有些云里雾里的,于是我亲自做了下测试和思考。
这里是代码部分:
package main
import (
"fmt"
)
func test(a *int) {
fmt.Println("传入变量的值:", a)
fmt.Println("传入变量的地址:", &a)
}
func main() {
va := 666
vad := &va
fmt.Println("需要传入的值:", vad)
fmt.Println("需要传入的值的地址", &vad)
test(vad)
}
这里是执行结果
需要传入的值: 0xc000018658
需要传入的值的地址 0xc000006058
传入变量的值: 0xc000018658
传入变量的地址: 0xc000006060
也就是说传入和实际接收的值都是指针变量,这个两个指针变量 vad
和 a
的值都为指针所指向的变量 va
的地址 0xc000018658
。
然后再看函数内部的这个传入的这个指针 a
的地址(指针)0xc000006060
,对比外面存放指针 vad
的地址 0xc000006058
,这两个值是不一样的,说明指针类型也是值传递,也就是说复制了一份指针的值传递给函数。
所以来说,函数 test
内部的 a
变量和外部的 vad
变量完全不是同一个东西,a
是vad
的复制体,但是这两个变量的值存放的都是va
变量的地址,所以操作 a
会对变量 va
产生修改。
从这里来看,个人觉得“ slice、map、channel、func
都是引用传递”的表述方式感觉容易引起误解,会怀疑golang
的设计对这几个东西特殊对待,是引用传递。
实际上golang
的设计,所有类型都是以值
的形式传递。只不过对这几种类型来说,底层的实现就是这几种类型的数据创建成功后,变量所接收的数据是这些类型所对应的地址,或者说被赋值的变量所接受到的是这几种类型的值的地址。而不应该是这几种类型在传递的时候是什么引用类型。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK