3个不同的函数作为goroutine启动,产生相同的goroutine(显然忽略参数)。

huangapple go评论84阅读模式
英文:

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()
}

huangapple
  • 本文由 发表于 2015年12月28日 22:35:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/34495465.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定