首页 > 解决方案 > 范围指针的 Golang

问题描述

我是 Golang 的新手,最近遇到了与此问题中描述的相同的问题:奇怪的 golang "append" behavior

所以我想知道在for range循环范围之外的任何地方使用循环中的对象副本是否基本上是不合适的——比如将它传递给一个单独的函数、附加它(如问题中所述)等等。

如果您计划对其进行变异,将其添加到该循环范围之外的列表等等,访问这样的对象几乎总是更合适,因为在下一个循环中您添加的指针会改变?

for index := range myList {
    doSomething(&myList[index])
}

标签: go

解决方案


您最需要记住的是 Go 是按值传递的如果您完全可以使用副本,完全理解突变不会反映,并且巨大结构的副本可能很昂贵,那么传递副本或指针是完全正当的理由。

如果您需要进行修改,请按照此处显示的方式通过引用传递,或者您也可以将它们作为指针存储在切片中以以 eg 开头[]*MyStruct。实际上,这揭示了他们在规范中专门选择通过复制传递结构的设计选择。

在幕后,aslice抽象了一个数组,但只是一个结构,称为切片头,带有指向数组的指针。当你传递一个 slice 时,header 是通过value传递的,但内容基本上由 3 个整数组成,因此复制它并不昂贵。这就是在使用 append 时必须重新分配变量以使其持久存在的原因,例如s = append(s, value). 您可以通过引用在代码中传递切片,但这样做不是惯用的 Go。


推荐阅读