去范围切片和goroutine方法调用,后面的逻辑

去范围切片和goroutine方法调用,后面的逻辑,go,goroutine,Go,Goroutine,代码如下所示: package main import ( "fmt" "time" ) type field struct { name string } func (p *field) print() { fmt.Println(p.name) } func main() { data := []field{{"one"},{"two"},{"thr

代码如下所示:

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循环变量在for循环范围中被重用

当goroutine有机会启动时,
v
的值可能已被修改。因此,打印结果将是
“三,三,三”

但当我们将数据变量修改为另一个声明时:

data := []*field{{"one"},{"two"},{"three"}}
打印结果将是“一、二、三”

我不明白为什么。指针有什么不同吗?或者它有什么不同的机制


这是我从学校读到的。但海报没有说明原因。或者它只是一个事件,输出是正确的。

在第一个循环中,
v
字段
项的值。由于
v
是可寻址的,因此它被自动引用为
print()
方法的指针接收器。因此
v.print()
正在使用
v
本身的地址,并且该地址的内容在循环的每次迭代中都会被覆盖


将声明更改为使用
*字段时,
v
现在是指向
字段
值的指针。在这种情况下,当调用
v.print()
时,您正在对
v
指向的值进行操作,该值存储在
数据中,对
v
的覆盖无效

第二次我看不出
数据
的定义有什么不同。@LutzHorn很抱歉输入错误和您的更正。第一个错误的情况是数据被定义为“数据:=[]字段{{“一”}、{“二”}、{“三”}”。而新的一个“数据:=[]*字段{{“一”}、{“二”}、{“三”}”,请提问并修复代码。没错,操作是在
数据
中存储的元素上进行的,但是操作的元素被
v
引用,当循环运行时,
v
被覆盖。当goroutine最终被调用时,v已指向最后一个元素。
v
如何保持对多个指针、结构值或其他内容的引用。或者我错过了一些机制,golang是否获取了
v
所指向的真实地址?或者
v
是否被获取,直到goroutine最终获得运行的机会?
v
值是预取或运行时间fetched@cilendeng例如我不明白你的问题。没有什么神奇的事情发生,在Go中,一切都是一个值,复制发生在赋值的时候。我知道了。一个新goroutine的参数会被计算并传递到当前gorouine上(很多时候当前goroutine是主goroutine)。但是它会在一个新goroutine上安排一段时间