26

Go语言之指针常见问题

 4 years ago
source link: https://studygolang.com/articles/25015
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.

原文来自于本人公众号,“灰子学技术”。

原文链接:https://mp.weixin.qq.com/s/1n_s5EDm5Sl75J4GKVWKOQ

在Go语言中,指针其实有下面几种表现形式,第一:指针;第二:接口;第三:slice;第四:map。

场景一:指针变量作为参数使用,会被复制一份指针变量

对于指针来说,最常见也最容易让人产生混淆的便是,指针作为参数传递的时候,到底是复制了一份指针变量,还是类似于C++的引用一样,使用的是传入之前的指针变量?

例子:

ZJF73mz.png!web

Output:

iqqYryV.png!web

介绍:

通过上面的例子输出结果来看,不管是指针,接口,slice还是map,只要它们作为参数传入函数,都是复制了一份指针变量, main函数和test函数中的指针变量的地址并不相同

main中和test中的 指针变量所指向的地址 都是一致的,甚至对指针,slice和map的数据在test中的改变都会在main中生效。

当然我们也能得出这样一个结论,接口,slice和map作为参数传递的时候,其实跟使用指针变量是一致的。

场景二:指针变量最好不要在go语句中使用

Go语言中的协程使用,要特别小心,因为goroutine的底层实现机制,不能保证哪一个协程会先被执行,也就是说协程的执行顺序是不可预期的。这样以来,在协程内部修改同一块内存的数值的话,并不保证输出结果,所以我们最好不要在协程内部去修改同一块内存的数值。

例子:

IzqMF3M.png!web

第一、二次Output:

eEnqamU.png!web

第三次Output:

bIzMzmY.png!web

介绍:

通过上面的例子来看,我们可以发现goroutine的机制导致,对指针的tmp的操作顺序不一致,导致输出的该更指针的数据值是不同的,所以,我们在使用go的时候,最好不要使用指针变量作为参数。具体场景如下所示:

场景一:只是读指针中的数据的话,可以使用指针变量做参数,不建议使用,除非参数的结构体很大,复制一份数据结构的话,非常耗时。

场景二:指针中的数据更改与goroutinue的执行顺序无关的话,可以使用指针变量做参数。

场景三:指针中的数据变化与执行顺序有关系,不能使用指针变量做参数。

场景三:循环使用slice的时候,更改其中数据的影响

下面的例子与指针的关系不是很大,但是大家往往会搞混,特别是C++的开发人员转学Go的情况下,因为很容易跟C++中的迭代器类比。

例子1:

nMNVbyr.png!web

介绍:通过输出可以看出,对n的值做修改,并不会改变nodes数组中的数据。原因是,range的使用中,n的复制操作。

例子2:

aeEB7rA.png!web

介绍:如果想对数组nodes中的数据做更改,可以采用下标的方法。原因是,下标对应的nodes中的数据元素就是数组中的值,这里相当于更改原变量的数值。

例子3:

yaYNzuj.png!web

介绍:也可以将数组中的元素变成指针,这样range中的n相当于对指针进行操作,指针对应的数据会被同时改掉。

例子4:

2qUBvqQ.png!web

介绍:在对range指向的数组nodes做删除操作之后,我们发现nodes中对应的值"the"被删掉了。但是range中的索引却没有被更改,依然变成了2 ,这导致了后续nodes的操作都混乱了。

场景四:循环使用map的时候,更改其中数据的影响

对于场景三中的例子1 和2,在map场景中都是一致的,原因参考场景三。

例子:

jUjMFfz.png!web

介绍:

通过输出我们可以看出来,在map的range操作中,就算我们删除一个元素,map中的数值会立马更新,同时后续的k值也会使用最新的。原因是map采用的是(Key,value)的对应关系,map更新了之后,key的值会跟着更新。

小结:

上面介绍的指针场景属于Go语言中比较常用,并且很容易出错的场景。

如果大家还有比较典型和常见的场景,还请不吝赐教,留言补充,笔者会后续补充上。

相关文章:

Go语言之指针:https://mp.weixin.qq.com/s/qXi-_e_nuVDnaiPfm2HIHQ

公众号“灰子学技术”:

7NvqAnf.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK