英文:
3 different funcs launched as goroutines produce the same goroutine (apparently ignore arguments)
问题
对于3个不同且独立的"c"
for _, c := range u.components { // u.components有3个成员
fmt.Printf("%v %v", c.name, c.channel) // 打印3个不同的name/channel对
go c.Listen(); // c的一个方法,监听channel c.channel
}
...在这个循环中启动了3个相同的goroutine,其中c.name和c.channel是相同的。
长版本(有注释的简短代码):
https://play.golang.org/p/mMQb_5jLjm
这是我的第一个Go程序,我确定我漏掉了一些明显的东西。有什么想法吗?
谢谢。
英文:
For 3 different and distinct "c"
for _, c := range u.components { // u.components has 3 members
fmt.Printf("%v %v", c.name, c.channel) // prints 3 distinct name/channel pairs
go c.Listen(); // a method of c that listens on channel c.channel
}
...launches 3 identical goroutines in which c.name and c.channel are identical.
The long version (commented, short code):
https://play.golang.org/p/mMQb_5jLjm
This is my first Go program, I'm sure I'm missing something obvious. Any ideas?
Thank you.
答案1
得分: 3
调用c.Listen()
是在闭包中使用了c的值,该值通过指针传递给Listen
函数,并且每次迭代都会更改该值。如果将方法调用视为方法表达式,更容易理解。
go (*component).Listen(&c)
在每次迭代中创建一个新的c值,以防止上一个值被覆盖:
for _, c := range u.components { // u.components有3个成员
c := c
fmt.Printf("%v %v", c.name, c.channel) // 打印3个不同的name/channel对
go c.Listen() // c的一个方法,监听channel c.channel
}
或者直接使用切片中包含的值:
for i := range u.components {
go u.components[i].Listen()
}
英文:
The call to c.Listen()
is closing around the value of c, which is passed via a pointer to Listen
, and each iteration changes that value. It's easier to visualize if you look at the method call as a method expression
go (*component).Listen(&c)
https://golang.org/doc/faq#closures_and_goroutines
Create a new value for c on each iteration to prevent the previous from being overwritten:
for _, c := range u.components { // u.components has 3 members
c := c
fmt.Printf("%v %v", c.name, c.channel) // prints 3 distinct name/channel pairs
go c.Listen(); // a method of c that listens on channel c.channel
}
Or use the value contained in the slice directly:
for i := range u.components {
go u.components[i].Listen()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论