Skip to main content

Go 的 for 迴圈進階寫法

Go 的設計哲學是「少即是多」,因此沒有 whiledo-while,所有迴圈都由 for 一手包辦。以下整理幾種在實務中常見、道地(Idiomatic)的進階寫法。


1. 略過不需要的變數(Blank Identifier)

使用 range 時若不需要 indexvalue,不能留空(Go 會編譯報錯),需用底線 _ 略過:

// 只想要 value,不想要 index
for _, v := range s2 {
fmt.Println(v)
}

// 只想要執行次數,不需要內容
for range s2 {
doSomething()
}

2. 同時遍歷兩個變數

for 的初始化區塊可宣告多個變數,適合雙指標或同步計數:

for i, j := 0, 10; i < j; i, j = i+1, j-1 {
fmt.Printf("i: %d, j: %d\n", i, j)
}

3. Range 的「值複製」陷阱

range 迴圈中,value 是原始元素的複製品,修改它不會影響原本的 slice。

寫法結果
錯誤v = v * 10 → slice 不變
正確s2[i] = s2[i] * 10 → 直接改到 slice
for i, v := range s2 {
v = v * 10 // 無效,改的是複本
s2[i] = s2[i] * 10 // 有效,改的是原 slice
}

4. 搭配 Select 處理 Channel

併發情境下常用 for + select 持續監聽多個 channel:

for {
select {
case msg := <-ch:
fmt.Println("收到訊息:", msg)
case <-done:
return
}
}

5. 標籤(Label)跳出外層迴圈

巢狀迴圈時,可用 Label 從內層直接 break 到外層:

OuterLoop:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if i == 1 && j == 1 {
break OuterLoop
}
}
}

總結

  • 優先使用 range:可讀性高、字串會按 rune 遍歷(正確處理 UTF-8)、可避免 off-by-one 錯誤。
  • 要改 slice 元素時,用 index 存取 s[i],不要改 range 回傳的 value。