英文:
How to explain golang slice range's phenomenon
问题
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)
for key, value := range m {
fmt.Println(key, value)
}
}
结果:
map[Allen:0xc42006a0c0 Tom:0xc42006a0c0]
Allen &{Tom 23}
Tom &{Tom 23}
如何解释切片的现象,在我看来,stu 应该是 s 的每个成员的地址,但从结果来看,s 具有相同的地址。
解释:
在这段代码中,切片 s 中的每个元素都是一个 student 结构体的实例。在 for 循环中,我们使用了 range 关键字来遍历切片 s,每次迭代都会将 stu 设置为当前元素的副本。然后,我们将 stu 的地址存储在 map m 中。
然而,由于 stu 是一个副本,它的地址在每次迭代中都是相同的。因此,最终 map m 中的所有值都指向了最后一个 stu 的地址。
要解决这个问题,我们可以通过创建一个新的 student 实例来存储 stu 的副本,而不是直接使用 stu 的地址。修改代码如下:
for _, stu := range s {
copyStu := stu // 创建 stu 的副本
m[stu.Name] = ©Stu // 存储副本的地址
}
这样,每次迭代都会创建一个新的副本,并将副本的地址存储在 map m 中,确保每个值都有不同的地址。
英文:
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)
for key, value := range m {
fmt.Println(key, value)
}
}
result:
> map[Allen:0xc42006a0c0 Tom:0xc42006a0c0]
>
> Allen &{Tom 23}
>
> Tom &{Tom 23}
How to explain Slice's phenomenon, in my opinion, stu should be the address of every member of s, but from the results, s has the same address.
答案1
得分: 5
应用程序正在获取局部变量stu
的地址。将代码更改为获取切片元素的地址:
for i := range s {
m[s[i].Name] = &s[i]
}
链接:https://play.golang.org/p/0izo4gGPV7
英文:
The application is taking the address of the local variable stu
. Change the code to take the address of the slice element:
for i := range s {
m展开收缩.Name] = &s[i]
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论