解码 Go 切片范围的行为
在 Go 中,切片是一种多功能数据结构,提供类似动态数组的功能。当迭代切片时,范围语法提供了一种访问其元素的便捷方法。但是,某些情况可能会导致意外行为。
请考虑以下代码,该代码创建学生结构体切片并使用对这些结构体的引用填充映射:
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 } fmt.Println(m) // map[Allen:0xc42006a0c0 Tom:0xc42006a0c0] }
预期行为是映射应包含对切片中每个单独学生结构的引用。然而,结果显示映射中的两个键都指向相同的地址。
可以通过理解范围循环中的 Stu 变量是切片元素的副本而不是引用来解释此行为。 Stu.Name 检索名称字段的副本,而 &stu 获取该副本的地址,从而为所有映射值提供相同的地址。
要更正此问题,代码应获取该副本的地址实际的切片元素:
for i := range s { m[s[i].Name] = &s[i] }
通过直接访问切片元素,我们获得对其唯一内存位置的引用,解决意外行为并确保映射包含对每个学生的引用结构。
以上是为什么 Go 的切片范围循环在与 Map 一起使用时会产生意外的行为?的详细内容。更多信息请关注PHP中文网其他相关文章!