在 Gleam 中,case 運算式可以依照條件執行程式碼。有了 case 運算式,就能把一個值與一個或多個_模式_進行比對。這種模式的其中一個例子是_字面值模式_,它會把值與字面值(例如1或"hello")進行比對。
case 運算式是以 case 關鍵字寫成的:
pub fn describe(number: Int) -> String {
case number {
0 -> "Zero"
1 -> "One"
}
}
雖然這看起來像其他語言裡的 switch 敘述,但當你也搭配其他模式一起使用時,模式比對才會真正展現它的價值。其中一種是_變數模式_,它可以讓你將值指定給一個變數。在這個例子中,如果 number 不是 0,變數 i 就會被指定為 number 的值:
pub fn describe(number: Int) -> String {
case number {
0 -> "Zero"
i -> "Non zero"
}
}
有時候,你可能想為模式加上額外的條件。這稱為_守衛_(子句),可以透過 if 關鍵字加上去:
pub fn describe(number: Int) -> String {
case number {
0 -> "Zero"
i if i < 0 -> "Negative number"
}
}
基於效能考量,守衛中只允許使用基本的數學與布林運算子,其他函式不能在守衛中使用。
在上面的例子中,並非所有可能的輸入都能找到相符的模式。編譯器會偵測到這點並輸出錯誤。這稱為_窮舉檢查_。要解決這個警告,就必須處理所有情況。為此,可以使用_丟棄模式_,它是一個能比對任何值的模式:
pub fn describe(number: Int) -> String {
case number {
0 -> "Zero"
i if i < 0 -> "Negative number"
_ -> "Positive number"
}
}
// No compiler error
在一個子句中可以用 | 分隔各模式,藉此比對多個模式。每個子句只能加上一個守衛:
pub fn describe(number: Int) -> String {
let yell = True
case number {
0 -> "Zero"
3 | 5 -> "One of the first odd prime numbers"
2 | 4 | 6 | 8 if !yell -> "One of the even numbers less than 10"
i if i % 2 == 0 && yell -> "[Yelling] I'm telling you! It's a even nunber"
i if i < 0 -> "Negative number"
_ -> "Positive number"
}
}
// No compiler error
case 運算式會由上而下依序用值去比對每個模式,直到找到相符的模式,並執行該模式對應的邏輯。模式的順序很重要!
在這個練習中,你會和朋友一起玩猜數字遊戲。規則很簡單:你偷偷在1到100之間選一個數字,朋友則試著猜出你選的是哪個數字。為了幫助朋友,你會根據猜測和你選的數字(42)有多接近,給出不同的回應。以下是各種回應的規則:
42:「Correct」41或43:「So close」41:「Too low」43:「Too high」你有四個任務,要分別實作這些猜測對應的回應。
實作reply函式,讓它能回應正確的猜測:
reply(42)
// -> "Correct"
修改reply函式,讓它能回應很接近的猜測:
reply(41)
// -> "So close"
修改reply函式,讓它能回應太低的猜測:
reply(25)
// -> "Too low"
修改reply函式,讓它能回應太高的猜測:
reply(88)
// -> "Too high"