通常情况下,一个简单的if/else 是不足够的,因为你可能有两个以上的选择。此外,条件可能变得相当复杂。Rust 有关键字match,允许你用更强大的 match 关键字,取代复杂的if/else 集合。如下所示:
let x = 5;match x {1 => println!("one"),2 => println!("two"),3 => println!("three"),4 => println!("four"),5 => println!("five"),_ => println!("something else"),}
match 采用表达式的形式,然后根据它的值来分支。分支的每个‘臂’都是val=>expression 的形式。当值匹配时,这个臂的表达式将被执行实现。之所以称之为 match 是因为‘模式匹配’的术语,而这种正是match 实现的形式。这里有一整章关于模式,包含了这里可能的所有模式。
那么大的优势是什么呢?这里有几个优势。首先,匹配保障‘穷尽性检查’。你是否看到了最后一个下划线 (_) ?如果我们删除该下划线,Rust 将会给出我们如下错误:
error: non-exhaustive patterns: `_` not covered
换句话说,Rust 试图告诉我们,我们忘记了一个值。因为x 是一个整数,Rust 知道它可以有许多不同的值 - 例如,6。然而,如果没有_,将没有可匹配项,所以 Rust 拒绝编译这段代码。_ 就像一个‘全匹配通配符’。如果其他的匹配项都不能匹配,将会匹配_ 的分支,由于我们有了全匹配通配符,我们现在对于x 的每个可能值都有一个匹配项,所以我们的程序将会被成功编译。
match 也是一个表达式,这意味着我们可以直接在一个let 绑定的右边使用它,或者直接作为表达式使用:
let x = 5;let number = match x {1 => "one",2 => "two",3 => "three",4 => "four",5 => "five",_ => "something else",};
有时它是将某种东西从一种类型转换为另一种类型的好方式。
match 关键字的另一个重要的用途是处理一个枚举的可能变量:
enum Message {Quit,ChangeColor(i32, i32, i32),Move { x: i32, y: i32 },Write(String),}fn quit() { /* ... */ }fn change_color(r: i32, g: i32, b: i32) { /* ... */ }fn move_cursor(x: i32, y: i32) { /* ... */ }fn process_message(msg: Message) {match msg {Message::Quit => quit(),Message::ChangeColor(r, g, b) => change_color(r, g, b),Message::Move { x: x, y: y } => move_cursor(x, y),Message::Write(s) => println!("{}", s),};}
再次,Rust 编译器检查内容详尽,所以它要求你对于枚举的每个变量都有一个匹配的臂。如果你遗漏了一个,它将会给你一个编译时错误,除非你使用_。
与之前使用的match 不同,你不可以使用正常的if 语句来做到这一点。你可以使用可以被看做match 的一种缩写形式的if let 语句。
关闭