如何解释Golang切片范围的现象

huangapple go评论78阅读模式
英文:

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] = &copyStu // 存储副本的地址
}

这样,每次迭代都会创建一个新的副本,并将副本的地址存储在 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] }

https://play.golang.org/p/0izo4gGPV7

huangapple
  • 本文由 发表于 2017年9月12日 14:27:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/46169351.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定