去范围切片和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上安排一段时间