先说清楚,在go中没有引用变量,所以更不存在什么引用传值了。
什么是引用变量在类C++语言中,你可以声明一个别名,给一个变量安上一个其他名字,我们把这称为引用变量。
#(){inta=10;intb=a;intc=b;printf("%p%p%p\n",a,b,c);//0x7ffe114f0b140x7ffe114f0b140x7ffe114f0b14return0;}你可以看到a,b,c都指向同一块内存地址,三者的值相同,当你要在不同范围内声明引用变量(即函数调用)时,此功能很有用。
Go中不存在引用变量与C++不同的是,Go中的每一个变量都有着独一无二的内存地址。
packagemainimport"fmt"funcmain(){vara,b,(a,b,c)//0x1040a1240x1040a1280x1040a12c}你不可能在Go程序中找到两个变量共享一块内存,但是可以让两个变量指向同一个内存。
packagemainimport"fmt"funcmain(){varaintvarb,c=a,(b,c)//0(b,c)//0x1040c1080x1040c110}在这个例子中,b和c拥有a的地址,但是b和c这两个变量却被存储在不同的内存地址中,更改b的值并不会影响到c。
map和channel是引用吗不是,map和channel都不是引用,如果他们是的话,下面这个例子就会输出false
packagemainimport"fmt"funcfn(mmap[int]int){m=make(map[int]int)}funcmain(){varmmap[int]intfn(m)(m==nil)}如果是引用变量的话,main中的m被传到fn中,那么经过函数的处理m应该已经被初始化了才对,但是可以看出fn的处理对m并没有影响,所以map也不是引用。
map是一个指向结构的指针,如果你还有疑问的话,请继续阅读下去。
map类型是什么当我们这样声明的时候。
m:=make(map[int]int)
编译器将其替换为调用/makemap[1]
//makemapimplementsGomapcreationformake(map[k]v,hint).//Ifthecompilerhasdeterminedthatthemaporthefirstbucket//canbecreatedonthestack,hand/orbucketmaybenon-nil.//Ifh!=nil,themapcanbecreateddirectlyinh.//!=nil,(t*maptype,hintint,h*hmap)*hmap
可以看到,makemap函数返回*hmap,一个指向hmap[2]结构的指针,我们可以从go源码中看到这些,除此之外,我们还可以证明map值的大小和uintptr一样。
packagemainimport("fmt""unsafe")funcmain(){varmmap[int]((m),(p))//88(linux/amd64)}如果map是指针的话,它不应该返回*map[key]value吗这是个好问题,为什么表达式make(map[int]int)返回一个map[int]int类型的结构?不应该返回*map[int]int吗?
IanTaylor在这个回答[3]中说:
所以说,Go把*map[int]int重命名为map[int]int
via:
作者:DaveCheney[4]译者:Jun10ng[5]校对:unknwon[6]
本文由GCTT[7]原创编译,Go中文网[8]荣誉推出