首页 >后端开发 >Golang >为什么 Go 中的切片范围迭代有时会返回副本而不是地址?

为什么 Go 中的切片范围迭代有时会返回副本而不是地址?

DDD
DDD原创
2024-12-05 15:54:14213浏览

Why Do Slice Range Iterations in Go Sometimes Return Copies Instead of Addresses?

理解 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn