迴圈是一種控制結構,可以根據指定的條件重複執行程式碼。
while 迴圈while 迴圈是一種控制結構,可以根據指定的條件重複執行程式碼。
只要條件的評估結果為真,while 迴圈裡的程式碼就會繼續執行。
while 迴圈常用於事先不知道會疊代幾次的情況,任何需要用到迴圈的場合也都能使用。
條件會先於迴圈裡的程式碼被評估,這表示如果條件為假,迴圈裡的程式碼就永遠不會被執行。
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 迴圈相同,差別在於迴圈裡的程式碼會持續執行,直到條件的評估結果為真。
這和 if 與 unless 之間的差別是一樣的。
i = 0
until i == 3
puts i
i += 1
end
while 迴圈常見的錯誤之一,是進入永遠不會結束的「無限迴圈」。
無限迴圈可能是因為某個條件永遠不會評估為真或假所造成的。
這通常是程式設計師的疏失,例如忘記遞增迴圈變數。
不過有時候,無限迴圈是實作程式邏輯最清楚的方式。
有時則是必須永遠迴圈下去,例如 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
在 Crystal 中,方法裡的最後一個運算式會回傳它的值。
不過,有時你會需要在最後一個運算式之前回傳值。
這時可以使用 return 關鍵字,它會回傳後面那個運算式的值。
寫在 return 關鍵字之後的程式碼不會被執行。
def speed_limit(road_number)
if road_number == 1
return 50
puts "This will not be executed"
elsif road_number == 2
return 80
puts "This will not be executed"
end
100
end
p speed_limit(1) # => 50
p speed_limit(2) # => 80
p speed_limit(3) # => 100
當方法裡的最後一個運算式就是要回傳的值時,應該省略 return 關鍵字。
在這個練習中,你會處理儲蓄帳戶。 每年,儲蓄帳戶的餘額會根據利率更新。 銀行給你的利率取決於你帳戶裡的金額(也就是餘額):
1000元時為 0.5%。1000元且小於5000元時為 1.621%。5000元時為 2.475%。你有四項任務,每項都會涉及你的餘額和它的利率。
實作方法SavingsAccount.interest_rate(),它接受一個餘額作為引數。
這個方法應該回傳指定餘額的利率。
SavingsAccount.interest_rate(200.75)
# => 0.5
實作方法SavingsAccount.interest(),它接受一個餘額作為引數。
這個方法應該回傳指定餘額的利息。
SavingsAccount.interest(200.75)
# => 1.00375
實作方法SavingsAccount.annual_balance_update(),它接受一個餘額作為引數。
這個方法應該回傳一年後的餘額。
SavingsAccount.annual_balance_update(200.75)
# => 201.75375
實作方法SavingsAccount.years_before_desired_balance(),它接受一個餘額和一個目標餘額作為引數。
這個方法應該回傳達到目標餘額所需的年數。
balance = 200.75
target_balance = 214.88
SavingsAccount.years_before_desired_balance(balance, target_balance)
# => 14
對本金餘額套用單利時,會把餘額乘以利率,兩者的乘積就是利息金額。
複利則不同,它是定期套用利息。 每次套用時都會計算出利息金額並加到本金餘額上,讓之後的利息計算都建立在更大的本金餘額之上。