写点什么

5 分钟速读之 Rust 权威指南(十)

用户头像
码生笔谈
关注
发布于: 2021 年 05 月 26 日
5分钟速读之Rust权威指南(十)

控制流 match 和 if let

rust 中有一个强大的控制流运算符:match,它允许将一个值与一系列的模式相比较,并根据匹配的模式执行相应代码,模式可由字面量、变量名、通配符和许多其他东西组成(后面章节会详细介绍)。

match 的简单使用

我们将创建一个包含 3 中 web 框架的枚举,根据枚举变体类型获取框架最新版本号:


// 定义一个框架枚举,包含3种框架的变体enum Framework {  Vue,  Angular,  React}
fn framework_version(framework: Framework) -> u32 { // 使用match关键字对framework进行匹配 match framework { // 模式 => 处理逻辑 Framework::Vue => 3, Framework::Angular => 12, Framework::React => { // 多行代码可以添加花括号 return 17 }, }}
println!("Vue: {}", framework_version(Framework::Vue)); // 3println!("Angular: {}", framework_version(Framework::Angular)); // 12println!("React: {}", framework_version(Framework::React)); // 17
复制代码

绑定值的模式

match 还可以绑定被匹配对象的部分值,而这也正是我们用于从枚举变体中提取值的方法:


#[derive(Debug)]enum VueState { // Vue框架的状态  Stable,  Next,}
enum Framework { Vue(VueState), // Vue框架变体关联一个状态类型 Angular, React}
fn framework_version(framework: Framework) -> u32 { match framework { Framework::Angular => 12, Framework::React => 17, Framework::Vue(state) => { // 首先匹配到Vue分支,然后将Next绑定到state上 match state { // 继续匹配state VueState::Stable => 2, VueState::Next => 3, } } }}
// 创建不同状态的Vue枚举let vue2 = Framework::Vue(VueState::Stable);let vue3 = Framework::Vue(VueState::Next);
println!("{}", framework_version(vue2)); // 2println!("{}", framework_version(vue2)); // 3
复制代码

匹配 Option<T>

上一章节中介绍过的 Option<T>,match 也可以将 Option::Some(T)中的 T 值取出:


fn unwrap(x: Option<i32>) -> i32 {  match x {    Option::None => 0, // 当是变体None时,返回0    Option::Some(num) => { // five匹配到Some分支,然后将5匹配到num上      num    },  }}
let option_five = Option::Some(5);let five = unwrap(option_five);let zero = unwrap(None);
println!("{:?}", option_five); // Some(5)println!("{}", five); // 5println!("{}", zero); // 0
复制代码

匹配必须穷举的所有可能

如果没有穷举(exhaustive)所有值,将会编译失败:


match framework {  Framework::Vue => 3,  Framework::Angular => 12,  // 报错,Framework::React 情况未覆盖}
复制代码

_通配符

有的时候,我们可能并不想要处理所有可能的值,rust 同样也提供了一种模式用于处理这种需求:


let some_u8_value = 10u8;match some_u8_value {  1 => println!("one"),  2 => println!("two"),  3 => println!("three"),  // 因为u8有255中可能,我们肯定不会穷举所有,只列出关心的即可,其他的用_代替  _ => println!("other")}// "other"
复制代码

if let 语法糖

由于 match 的穷举性要求,当我们只关心某一种情况时,代码写起来还是比较繁琐,这时我们可以使用 if let 语法糖来解决:


let some_u8_value = Option::Some(3u8);
// match方式match some_u8_value { Option::Some(3u8) => println!("three"), _ => println!("other")}// "three"
// if let方式if let Option::Some(3) = some_u8_value { println!("three")} else { // else是可选的,相当于match分支中的 _ => println!("other") println!("other")}// "three"
复制代码


我们再看一下最上边 web 框架的例子,使用 if let 代替 match:


let vue2 = Framework::Vue(VueState::Stable);let vue3 = Framework::Vue(VueState::Next);
// match方式match vue2 { Framework::Vue(state) => { println!("{:?}", state) } _ => println!("other")}// Stable
// if let方式if let Framework::Vue(state) = vue3 { println!("{:?}", state)} else { println!("other")}// Next
复制代码


发布于: 2021 年 05 月 26 日阅读数: 9
用户头像

码生笔谈

关注

欢迎关注「码生笔谈」公众号 2018.09.09 加入

前端、Rust干货分享,一起成为更好的Javascripter & Rustacean

评论

发布
暂无评论
5分钟速读之Rust权威指南(十)