用 time.Sleep 等 goroutine 只是 demo 寫法
教學裡常用
time.Sleep讓main撐著等 goroutine 印完,那只是為了看到輸出的權宜之計。它同時犯了兩個錯:猜太短會漏掉結果,猜太長是白白浪費時間——而且沒有任何一個數字是對的,因為它賭的是排程時機。
func main() {
ch := make(chan string)
go send(ch)
go receive(ch)
time.Sleep(2 * time.Second) // ← 只是 demo
}正解是讓程式等一個事件,而不是等一段時間:
// 一條:直接在 main 收,channel 本身就是同步點
func main() {
ch := make(chan string)
go send(ch)
fmt.Println(<-ch) // 收到才往下走
}
// 多條:用 WaitGroup 數人頭
var wg sync.WaitGroup
for _, s := range items {
wg.Add(1)
go func(s string) { defer wg.Done(); work(s) }(s)
}
wg.Wait()同一個判斷可以套用在測試上:任何寫 sleep(500) 等非同步結果的測試,都是把「等事件」換成「等時間」,於是在慢一點的機器上就變成 flaky。