match使用
在rust中提供了一个极为强大的控制流运算符match
match
允许一个值与一系列模式进行匹配,并执行匹配的模式对应的代码- 这些模式可以是
子面值
、变量名
、通配符
等等
来个例子
fn main() {println!("penny {}", value_in_cents(Coin::Penny)) // penny 1
}enum Coin {Penny,Nickel,Dime,Quarter,
}fn value_in_cents(coin: Coin) -> u8 {match coin {Coin::Penny => 1,Coin::Nickel => 5,Coin::Dime => 10,Coin::Quarter => {println!("多行的情况需要加上花括号");25},}
}
绑定值的模式
匹配的分支可以绑定到被匹配对象的部分值,因此我们可以从enum
变体中获取值
fn main() {println!("penny {}", value_in_cents(Coin::Quarter(UsState::Alabama))) // State quarter from Alabama\n penny 25
}#[derive(Debug)]
enum UsState {Alabama,Alaska,
}enum Coin {Penny,Nickel,Dime,Quarter(UsState),
}fn value_in_cents(coin: Coin) -> u8 {match coin {Coin::Penny => 1,Coin::Nickel => 5,Coin::Dime => 10,// 绑定值的模式匹配Coin::Quarter(state) => {println!("State quarter from {:?}", state);25},}
}
在rust的match匹配中,必须要穷举所有的变体
但是如果match
要匹配的变体
太多了,我们不想处理那么多该怎么办呢?
- 可以使用通配符
_
来替代其余没列出的值
fn main() {let v = 0u8;match v {1 => println!("one"),2 => println!("two"),3 => println!("three"),// 其他的不想匹配了,可以使用`_`替代,下换线通配符只能放到最后一行_ => println!("other")}
}
match语法糖【if let】
上述的例子可以使用if let
控制流进行改写
fn main() {let v = 0u8;match v {1 => println!("one"),2 => println!("two"),3 => println!("three"),// 其他的不想匹配了,可以使用`_`替代,下换线通配符只能放到最后一行_ => println!("other"),}// 可以使用let进行简写if let 3 = v {println!("three");} else {println!("other")}
}
小结一下if let
的作用
- 处理只关心一种匹配二忽略其他匹配的情况
- 更少的代码、更少的缩进、更少的模板代码
- 放弃了穷举的可能
- 我们可以把
if let
当做是match
的语法糖
匹配Option
fn main() {let five = Some(5);let six = plus_one(five);let none = plus_one(None);// 使用模式匹配和Option可以避免其他语言出现NPE的问题match six {Some(value) => println!("six: {}", value),None => println!("six: None"),}match none {Some(value) => println!("none: {}", value),None => println!("none: None"),}
}fn plus_one(x: Option<i32>) -> Option<i32> {match x {None => None,Some(i) => Some(i + 1)}
}