golang执行range的时候如果用了go开启多协程为啥不能传递地址

在 for a,b := range c 遍历中, a 和 b 在内存中只会存在一份,即之后每次循环时遍历到的数据都是以值覆盖的方式赋给 a 和 b,a,b 的内存地址始终不变

type Person struct {
    Name string
}

func TestRange(t *testing.T) {
    var l = []Person{
        {Name: "a"},
        {Name: "b"},
        {Name: "c"},
    }
    for k, v := range l {
        go Echo(&v, k)
    }
    time.Sleep(time.Second * 2)
}

func Echo(u *Person, idx int) {
    fmt.Printf("name = %s,idx = %d\n", u.Name, idx)
}

输出的结果是:

name = c,idx = 2
name = c,idx = 0
name = c,idx = 1

如果没有 go 多协程顺序执行是正常的,但是开启协程以后就不正常了,主协程range肯定跑得最快的,也就是最后一个值 v == c 的时候执行完,开始运行输出,此时3个协程的u指向同一块内存,也就是 name == c

 

posted @ 2022-06-19 00:32  许伟强  阅读(106)  评论(0编辑  收藏  举报