case(在其他語言中常被稱為 switch)是一種像 if-else 一樣的控制運算式。
case允許串接多個 if-else-if 敘述,可以更具可讀性,也能實現強大的結構。
一個case由關鍵字case定義,後面接著一個選用的運算式。
接著,針對每個 case,會使用關鍵字when,後面接著一個與 case 運算式相比較的運算式。
when關鍵字不應相對於case關鍵字縮排。
when關鍵字之後,是當 case 運算式符合 when 運算式時應該執行的程式碼。
case 允許一個選用的else敘述,當沒有其他 case 符合時便會執行它。
case 運算式會被求值,然後與每個 when 運算式相比較。
運算式是使用 case subsumption 運算子(===)進行比較。
case 1
when 1
puts "One"
when 2
puts "Two"
else
puts "Other"
end
# => One
# This is the same as:
tmp = 1
if 1 === tmp
puts "One"
elsif 2 === tmp
puts "Two"
else
puts "Other"
end
===)case subsumption 運算子(===)與相等運算子(==)有點不同。
這個運算子會檢查右邊是否為左邊所描述集合的成員。
這表示每個運算元擺放的位置確實有影響。
運作方式取決於左邊的型別,例如Range會檢查右邊是否在該範圍內,而Object會檢查右邊是否為Object的實例。
(1..3) == 1 # => false
(1..3) === 1 # => true
String == "foo" # => false
String === "foo" # => true
case 允許在單一 case 中比對多個運算式,每個可能的值以逗號分隔。 只要任一個運算式符合,就會執行該程式碼。 這在單一 case 有多個可能值時很有用。
case 1
when 1, 2
puts "One or two"
else
puts "Other"
end
case 也可以檢查某個值是否在範圍內。 做法是把範圍當作 when 運算式。
case var
when 1..3
puts "One to three"
else
puts "Other"
end
當不需要 case 運算式時,可以將它省略。 這麼做會讓每個 when 運算式都改以真值來判斷。 並讓它們的行為表現得像 if-else-if 敘述。
case
when 1 == 1
puts "One is equal to one"
when 1 > 2
puts "One is greater than two"
else
puts "Other"
end
Crystal 允許單行的 case 敘述。
當你有簡單的單行敘述時可以使用。
單行 when 敘述寫成when <expression> then <statement>.
而用在 else 敘述時,則寫成else <statement>。
case var
when 1 then puts "One"
when 2 then puts "Two"
else puts "Other"
end
case 允許搭配型別進行比對。
比較時會使用is_a?運算子來檢查變數的型別。
例如,這讓聯合型別中的每個型別都能有一個分支。
case var
when Int32
puts "Int32"
when String
puts "String"
else
puts "Other"
end
case 允許使用隱式物件。 這讓 when 運算式可以是對 case 運算式的方法呼叫。 根據方法回傳的是真值還是假值,決定這個 case 是否符合。
case 1
when .odd?
puts "Odd"
when .even?
puts "Even"
end
case 允許窮舉的 case,這表示可以確保所有可能的值都被處理到。
它類似於 when 敘述,但改用in關鍵字而非when。
當 case 是窮舉的,它不支援任何when或else敘述。
窮舉的 case 可以用在Bools、Union型別、Enum和Tuples上。
後面兩者會在之後的概念中介紹。
窮舉的 case 代表所有可能性都必須被處理,否則會引發編譯錯誤。
以窮舉的 case 處理Union型別,類似於非窮舉的 case。
var : (Int32 | String | Bool)
case var
in Int32
puts "Int32"
in String
puts "String"
in Bool
puts "Bool"
end
Bools可以使用true和false關鍵字,以窮舉的 case 來處理。
var : Bool
case var
in true
puts "True"
in false
puts "False"
end