用 time.Sleep 等 goroutine 只是 demo 寫法

教學裡常用 time.Sleepmain 撐著等 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

相關:無緩衝 channel 的收送會互相等待Goroutine 是用 go 關鍵字啟動的輕量任務