这段代码的主要问题,父级协程没有等待子协程完成就退出了。但是,你这里是有 sleep 的,所以应该是有结果的,只是不能保证完全执行结束才退出。

之前回答过一个类似的问答。

Go 中,可以用 Go 提供的两种机制实现,分别是通过 sync 或 channel 实现协程间的信息同步。可以通过你的这个例子,简单看看这两种方式怎么写。

使用 sync.WaitGroup 通信

wg.Add(1) 增加计数,wg.Done() 执行会将 wg 的计数减一。而 wg.Wait 会一直等待,直到 wg 的计数变为 0,即子协程完成任务,才会退出。

使用 channel 通信

<-done 将会等待从 channel 中读取数据,直到 say 中执行了 done <- struct{}{} ,即子协程完成任务,才会退出。

这两种方式都能保证 Println(a) 在 a = "Hello World" 之后执行,即 setup 完成后执行。虽然,Go 提倡以 channel 方式在协程间同步信息,但如果只是强调任务是否完成,或许 WaitGroup 更好。

关于 Go 中的协程间通信,Go 官网有篇文章写得非常好,我最近翻译了一版,如果要学习 Go 的并发编程,建议可以去读一下。


欢迎关注我的专栏,Golang 之旅,见证我的 Golang 学习历程。