英文:
Goroutine called in a loop on function with pointer overwrites value?
问题
我刚刚开始学习Go语言,并遇到了指针在这种语言中如何处理的问题。
我有以下代码,但无法弄清楚如何修复它以获得正确的响应。
将func (me *Str) Start()
更改为func (me Str) Start()
可以解决问题,但我需要将其作为引用来编写此结构(其中将包含通道)。
示例代码(https://play.golang.org/p/EsPejyCrX7):
package main
import (
"fmt"
"sync"
)
var wg1 sync.WaitGroup
type Str struct {
id int
}
func (me *Str) Start() {
wg1.Add(1)
fmt.Println("F1 ", me)
go me.startFn()
}
func (me *Str) startFn() {
defer wg1.Done()
fmt.Println("F2 ", me)
}
func main() {
Fl2 := []Str{
{1},
{2},
{3},
}
for _, fl := range Fl2 {
fl.Start()
}
wg1.Wait()
}
响应:
F1 &{1}
F1 &{2}
F1 &{3}
F2 &{3}
F2 &{3}
F2 &{3}
预期响应(F2 可能是随机的):
F1 &{1}
F1 &{2}
F1 &{3}
F2 &{3}
F2 &{2}
F2 &{1}
英文:
I have just started playing with Go and stumbled upon problem how the pointers are handled in this language.
I have such code and can`t figure out how to fix it to get the correct response.
Changing func (me *Str) Start()
to func (me Str) Start()
fixes the problem, but I need this as reference to write this structure (it will have channel in it).
Sample code (https://play.golang.org/p/EsPejyCrX7):
package main
import (
"fmt"
"sync"
)
var wg1 sync.WaitGroup
type Str struct {
id int
}
func (me *Str) Start() {
wg1.Add(1)
fmt.Println("F1 ", me)
go me.startFn()
}
func (me *Str) startFn() {
defer wg1.Done()
fmt.Println("F2 ", me)
}
func main() {
Fl2 := []Str{
{1},
{2},
{3},
}
for _, fl := range Fl2 {
fl.Start()
}
wg1.Wait()
}
Response:
F1 &{1}
F1 &{2}
F1 &{3}
F2 &{3}
F2 &{3}
F2 &{3}
Expected response (F2 can be random):
F1 &{1}
F1 &{2}
F1 &{3}
F2 &{3}
F2 &{2}
F2 &{1}
答案1
得分: 2
在循环迭代变量上使用goroutines是一个常见的错误。
通过范围索引调用Fl2
元素的.Start
方法,而不是范围值(playground):
for i := range Fl2 {
Fl2[i].Start()
}
然而,由于goroutines的调度,输出可能仍然不会完全符合您的期望,例如可能会像这样:
F1 &{1}
F1 &{2}
F1 &{3}
F2 &{3}
F2 &{1}
F2 &{2}
英文:
Using goroutines on loop iterator variables is a common mistake.
Call .Start
on the element of Fl2
by the range index, instead of the range value (playground):
for i := range Fl2 {
Fl2[i].Start()
}
However, the output might still not become exactly as you expect,
due to the scheduling of the goroutines,
for example it might be like this:
F1 &{1}
F1 &{2}
F1 &{3}
F2 &{3}
F2 &{1}
F2 &{2}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论