迴圈是一種控制結構,能讓程式碼根據指定的條件重複執行。
while 迴圈while 迴圈是一種控制結構,能讓程式碼根據指定的條件重複執行。只要條件評估為 truthy,while 迴圈內的程式碼就會持續執行。當事先不知道會疊代幾次時,通常會使用 while 迴圈,不過任何需要迴圈的情況都可以使用它。
條件會在迴圈內的程式碼執行之前先被評估,這表示如果條件為 false,迴圈內的程式碼就永遠不會執行。
i = 0
while i < 3
puts i
i += 1
end
# Output:
# 0
# 1
# 2
想逐一走訪一個字串時,可以對字串的長度進行迴圈。
str = "Hello"
i = 0
while i < str.size
puts str[i]
i += 1
end
# Output:
# H
# e
# l
# l
# o
until 迴圈until 迴圈的運作方式和 while 迴圈相同,差別在於迴圈內的程式碼會持續執行,直到條件評估為 truthy 為止。這就跟 if 與 unless 之間的差別一樣。
i = 0
until i == 3
puts i
i += 1
end
使用 while 迴圈時常見的錯誤,是進入一個永遠不會結束的「無限迴圈」。無限迴圈可能是因為條件_永遠_不會評估為 truthy 或 falsey所造成的。這通常是程式設計師的疏失,例如忘記遞增迴圈變數。但有時候,無限迴圈是實作程式邏輯最清楚的方式。有時則是必須永遠迴圈,例如 HTTP 伺服器會等待連線進來、處理它,然後再等待下一個連線。
breakbreak 關鍵字可以用來提早離開迴圈。當你想在特定條件下提早離開迴圈時,這會很方便。
i = 0
while i <= 3
puts i
i += 1
if i == 2
break
end
end
# Output:
# 0
# 1
nextnext 關鍵字可以用來跳到迴圈的下一次疊代。當你想跳過迴圈中特定的疊代時,這會很方便。
i = 0
while i <= 3
i += 1
if i == 2
next
end
puts i
end
# Output:
# 1
# 3
變數的型別在迴圈中可能會不一樣。在下面的範例中,a 的型別是 Int32 | String,因為在迴圈的前半段它可能是 Int32 或 String。變數 a 只在迴圈的前半段帶有 Int32 | String 型別,因為迴圈開始時它持有 Int32,到了第二次疊代則持有 String。這個多重型別系統之後會詳細說明。但因為我們確定迴圈的後半段只會持有 String,所以 a 在迴圈後半段的型別是 String。在執行階段,它永遠不會同時持有 Int32 和 String。
i = 0
a = 4
while i < 3
p typeof(a)
# => Int32 | String
a = "4"
p typeof(a)
# => String
i += 1
end
while 當作運算式使用while 可以當作運算式使用,這表示它可以是變數的值。它回傳的值,是透過 break 關鍵字所給的值,並不會回傳迴圈中最後一個運算式的值。
a = while true
break 1
end
p a
# => 1
i = 0
a = while i == 0
i += 1
1
end
p a
# => nil