在 Go 中,切片是一种强大的可以迭代的数据结构超过使用 range 关键字。然而,在一个特殊的现象中,当使用 for-range 迭代结构体切片时,结果映射中的元素共享相同的地址。这种行为可能会令人困惑,特别是因为原始切片中的元素应该具有唯一的地址。
理解这种现象的关键在于变量的方式存储在内存中。当访问 for-range 循环中的切片元素(本例中为 stu)时,局部变量 Stu 保存该结构的副本。将指针分配给局部变量可以有效地将映射中的所有元素指向内存中结构体的同一副本。
要解决此问题,分配切片元素的地址,必须修改代码以获取切片元素本身的地址。通过使用 s[i] 而不是 Stu,指向切片中实际元素的指针被分配给映射。
package main import "fmt" 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 i := range s { m[s[i].Name] = &s[i] // Change here } fmt.Println(m) for key, value := range m { fmt.Println(key, value) } }
输出:
map[Allen:0xc0000a6058 Tom:0xc0000a6060] Allen &{Allen 24} Tom &{Tom 23}
通过了解底层内存管理行为,我们可以解决这种切片范围现象 去。通过获取切片元素本身的地址,我们确保映射中的每个元素都指向内存中唯一的结构体,从而保持数据完整性。
以上是为什么 Go Slice Range 循环在映射结构时会创建共享地址?的详细内容。更多信息请关注PHP中文网其他相关文章!