Go 让操作 Slice 和其他基本数据结构成为一件很简单的事情。对于来自 C/C++ 令人畏惧的指针世界的人来说,在大部分情况下使用 Golang 是一件令人幸福的事情。对于 JS/Python 的使用者来说,Golang 除了语法之外,没有什么区别。

然而,JS/Pyhon 的使用者或是 Go 的初学者总是遇到使用指针的时候。下面的场景就是他们可能会遇到的。

场景

[]*string{}

让我们看一段代码。

strconv.Itoa#append

运行上面的代码片段,你得到的输出是

#9

调式代码的输出为

我看到他们被添加到...
这种事情怎么发生到我头上了?
$@#! 啊啊啊啊啊!!

朋友,放轻松,让我们看看到底发生了什么。

0x3AF1D234

现在让我们从 0 循环至 9。

第一次迭代[i=0]

"#0"numberString
numberString&numberString0x3AF1D234listOfNumberStrings
listOfNumberStrings

第二次迭代[i=1]

我们重复以上步骤。

"#1"numberString
numberString0x3AF1D234listOfNumberStrings
listOfNumberStrings

希望现在已经开始让你明白发生什么了。

0x3AF1D234numberString
numberString"#1"

重复以上步骤直到迭代结束。

numberString"#9"
*
0x3AF1D234
"#9"

解决方案

numberString
for
numberString
go build -gcflags "-m"&numberString

然后我们用生成的字符串更新变量,把它的地址添加到切片中。这样的话,切片中的每一个元素都存储着独一无二的内存地址。

上面的代码的输出将会是

我希望这篇文章能够帮助到一些人。我起写这篇文章的念头是因为我与一名公司初级工程师的经历,他遇到了相似的场景,并且完全绕不出来。这让我想到了我掉进类似陷阱的情况,那时候我是一名前公司的 C 语言初级工程师。

Ps. 如果你来自 C/C++ 中奇妙的指针世界......老实说,你已经遇到了这个错误(并从中学习)!



本文由 原创编译, 荣誉推出