为了账号安全,请及时绑定邮箱和手机立即绑定

`range` 返回的迭代值的数据类型是什么?

`range` 返回的迭代值的数据类型是什么?

Go
千巷猫影 2022-05-23 15:09:33
type Student struct {    Name string    Age  int}func main() {    data := make([]*Student, 0)    src := []Student{        Student{Name: "allen", Age: 30},        Student{Name: "tom", Age: 33},    }    for _, m := range src {        data = append(data, &m) // notice point!!!    }    for _, s := range data {        fmt.Println(*s)    }}为什么这段代码可以在 Go 中工作?输出与预期的相反,如下所示。{tom 33}{tom 33}代替{allen 30}{tom 33}我发现的一个解释是它m是一个固定指针,因此每次append(data,&m)只附加 的地址m,在迭代期间保持不变。然而,根据这个解释,m似乎是*Student,所以&m是**Student,但是如何将 value( &m)**Student附加到 的数组中[]*Student?去
查看完整描述

3 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

在切片上进行测距时,每次迭代都会返回两个值。第一个是索引,第二个是该索引处元素的副本。

因此,它具有您正在迭代的数组/切片的值。

在您的情况下,该值是一个Student结构


查看完整回答
反对 回复 2022-05-23
?
慕沐林林

TA贡献2016条经验 获得超9个赞

实际上它与 Go 中的事实有关,一切都是按值传递的。


m := range src

m始终是相同的参考,并且其值会更新。一个简单的查看方法是打印地址


for _, m := range src {

    // ---

    p := &m

    fmt.Printf("%p\n", p)

    // ---

    data = append(data, &m) // notice point!!!

}

可以在这里找到解释您的确切问题的好帖子iterate-over-slices-in-go


查看完整回答
反对 回复 2022-05-23
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

首先,您可以使用自省来找出是什么m。此外,您可以var m ...在循环之前将其 ( ) 声明为实验。

现在,你写“我发现的一个解释是 m 是一个固定指针”。首先,我不确定您所说的“固定指针”是什么意思,我也不认为您会这样做。固定(或恒定)的是 的地址m。结论是“因此每次都append(data,&m)只是附加”的地址m,这正是正在发生的事情。m但是,您对“似乎是”的假设*Student是有缺陷的,而是m类型Student,就这么简单。


查看完整回答
反对 回复 2022-05-23
  • 3 回答
  • 0 关注
  • 140 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号