在課程中一直聽到pattern、arm、match guard,就去查了一下意思。
以前篇文章的程式舉例:
fn even_and_odd(number: i32) -> String {
match number {
x if x % 2 == 0 => format!("{} is an even number.", x), // 這是 arm(分支)
y if y % 2 != 0 => format!("{} is an odd number.", y), // 這是另一個 arm
_ => unreachable!(), // fallback arm
}
}
元素 | 說明 |
---|---|
match number { ... } |
整個 match 敘述,用來比對 number 的值 |
x 、y 、_ |
這些是 pattern(模式),用來匹配 number 的實際值 |
每一對 模式 => 表達式 |
被稱為 arm(分支),是一整段邏輯,例如: x if ... => ... |
if x % 2 == 0 |
這是 match guard(模式守衛),附加在 pattern 後,加入額外條件做進一步判斷 |
其中,match guard:
就是附加在某個 pattern 後面的 if 條件,是「條件式 + 模式」的結合,用來更精細地判斷這個 arm 是否要觸發,本質上來說,「if x % 2 == 0」是條件式,但在 match 的語境中,它有個特別名稱,叫做 match guard。
另外,在網路上看到有人討論match問題,就記錄一下,原本的問題是:
let number: u8 = 4;
match number {
i if i == 0 => println!("Zero"),
}
這段會錯誤,錯誤訊息是「match 不完整」。
match number {
i => println!("Zero"),
}
但是這段卻不會報錯。原發問者認為是不是「帶有 guard 的分支不會被考慮」?
網友先是舉例:
這段會編譯錯誤(即使邏輯上好像涵蓋所有值):
match number {
i if i >= 0 => { 1 },
i if i < 0 => { 0 },
}
又或者以下這段:
match number {
i if true => { 0 },
}
而後回答:因為引用的文件並不是說「帶有 guard 的分支不會被考慮」,而是說:
「條件式(guard condition)不會被考慮」。
這表示,即使你用 guard 條件把所有可能的值都「邏輯上」涵蓋了,編譯器也不會這樣認為,因為它只看「模式(pattern)本身」,不看你後面加的 if 條件。