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

go for range slice 和 goroutine 方法调用,背后的逻辑

go for range slice 和 goroutine 方法调用,背后的逻辑

Go
青春有我 2021-10-11 10:42:49
代码如下:package main    import (        "fmt"        "time"    )    type field struct {        name string    }    func (p *field) print() {        fmt.Println(p.name)    }    func main() {        data := []field{{"one"},{"two"},{"three"}}        for _,v := range data {            go v.print()        }        time.Sleep(3 * time.Second)    }我知道代码是错误的,因为在 for-range 循环中重用了 for 循环变量。当 goroutine 有机会启动时,vmight的值已被修改。所以打印结果将是"three,three,three".但是当我们将数据变量修改为另一个声明时:data := []*field{{"one"},{"two"},{"three"}}打印结果将为"one ,two,three".我不明白为什么。指针有什么不同或有什么不同的机制吗?我从这篇文章中读到了这个。但海报没有说明原因。或者这只是一个事件,输出是正确的。
查看完整描述

1 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

在第一个循环中,v是一个项目的field。因为v是可寻址的,所以它被自动引用为该print()方法的指针接收者。所以v.print()使用的地址v本身,而地址的内容被覆盖在循环的每次迭代。

当您更改声明以使用 a 时*fieldv现在是一个指向field值的指针。v.print()在这种情况下调用时,您正在操作v指向的值,该值存储在 中data,并且覆盖v无效。


查看完整回答
反对 回复 2021-10-11
  • 1 回答
  • 0 关注
  • 195 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信