理解 Go 中的切片范围现象
在 Go 中,切片范围的行为可能会令人困惑。当使用 range 子句迭代切片时,人们很容易相信迭代变量保存了每个元素的地址。然而,情况并非总是如此。一种这样的场景是使用结构体和映射时。
考虑以下代码:
type student struct { Name string Age int } func main() { m := make(map[string]*student) s := []student{ {Name: "Allen", Age: 24}, {Name: "Tom", Age: 23}, } for _, stu := range s { m[stu.Name] = &stu } }
此代码迭代结构体切片,将键值对添加到映射中每个结构体,并将结构体的地址存储为值。然而,生成的映射显示所有值都指向相同的地址。
为了解释这种现象,我们需要看看切片范围的底层实现。当使用 range 子句迭代切片时,迭代变量会从切片接收元素的副本。因此,迭代变量保存结构体的副本,而不是其地址。
要解决此问题并将结构体的地址存储在映射中,必须修改代码以获取切片元素的地址:
for i := range s { m[s[i].Name] = &s[i] }
此更改可确保迭代变量保存结构体的地址,并且映射将正确存储切片中每个结构体的地址。
以上是为什么 Go 中的切片范围迭代有时会返回副本而不是地址?的详细内容。更多信息请关注PHP中文网其他相关文章!