坏蛋Dan
知乎@坏蛋Dan
发布时间:2024.1.3

前言

昨天我们学了enum以及Option

坏蛋Dan:rust基础学习--day12

今天我们继续往下学


match控制流结构

其实我们之前就用过了,在第二天写一个猜数游戏。

坏蛋Dan:rust基础学习--day2

在比对数值的时候就用了这个match模式匹配,匹配比较的变体(variant),有大于、小于以及等于三种变体。

match可以用于字面量、 变量、通配符等其他各种东西匹配,是非常强大的功能。

我们来看下一个例子

我们先是声明了一个枚举Coin,然后又声明了一个函数value_in_cents,参数是Coin也就是枚举类型,返回一个u8的数据。

之前有一个点我们忘了说了,枚举的变体是可以不用设置默认值的

我们跑下代码

我们先是声明了一个Coin的变体Penny 然后matchCoin这个枚举的所有变体(variant)。 接着匹配到了一个penny便士值输出为1。

模式匹配的关键字是match,然后跟匹配的目标, 然后就是{}

所以结构是这样:match xxx {}

=> 1=> { 1 }的简写,表示匹配到的语句。

Coin::Penny => 1这一条语句被叫做arms.

每条arms或者说是表达式的返回值都将作为这个match表达式的返回值。

这种代码在js中一般用对象匹配或者if条件判断等,用if条件判断会有些冗长,而用对象匹配的话会有些拘束性。

模式绑定值(patterns that bind to values)

这名字。。。我真的不知道翻译成啥

还记得我们昨天学的enum的变体可以绑定一个数据吗?这个绑定可以用于match中,我们来看下。

还是我们的硬币枚举,

不同的是四分之一镑(25美分)绑定了一个UsState的枚举。

然后我们再改下方法value_in_cents

和之前不同的是Coin::Quarter后面还接上了(state)

然后我们来调用下

如果匹配到了这个quarter的变体,就会把这个UsState::Alabama的枚举变体当做state这个变量传入大括号中作为参数。


匹配Option

还记得昨天我们学的Option这个类型吗?

它也能用来匹配,而且也非常是和match,用来判断一个值是否有效

我们创建了三个变量five、six、none以及plus_one方法

当我们匹配到None这个变体的时候就返回None,而Some的时候就返回Some(i + 1)

我们来打印下


match需要全面(match are exhaustive)

啥意思捏?其实很容易理解,按rust强调的安全性,如果你一个match只匹配了一个场景,但实际上存在多个场景,这时候就有可能引起报错,所以rust中使用match需要你穷举所有场景,这样才能保证不会出错。

但是这样是不人道的,因为你这个枚举可能有N个值,比如:我们全国各地的美食doge~

所以官方提供了一种方式允许你不处理其他场景,专注于其中某几个场景。

往下看。


全捕获模式和_占位符(catch-all patterns and _ placeholder)

上面的代码执行了之后会走other这个arms

这样你就能专注于37的场景,其他场景统一处理。

另外,如果我们不想处理other场景,这样也是可以的,比如:

_这个符号是获取不到值的,所以它并不能用于参数,它仅仅表示一个占位符,用在你完全不想处理其余场景时。

但是如果你没有列举所有场景时不写是不行的哦。《安全》

如果我们只想处理一种场景,其他场景都不想处理,这个时候rust还提供了一种方式来简写


使用if let简洁化控制流(concise control flow with if let)

如标题所说,上面提到的只需要处理一种情况的场景可以用if let来简洁match的用法。

比如原来我们需要用这样写

虽然挺简洁了,但是我们还想更简洁,就像js函数声明改成箭头函数一样(不是很恰当,因为函数声明和箭头函数两者不同点挺多)

我们可以用if let改成下面这个样子

只处理Some(max) = config_max的场景,而不处理None的场景。

但如果我们还想处理None的场景呢?(事真多)

其实也是可以滴,既然有if那自然有else,比如:

可以调整为

不过用不用取决于你自己~


总结

今天我们学了match模式匹配,以及全捕获匹配和if let等。

明天居家,隔壁老哥阳了~

如果觉得对你用帮助,麻烦点个赞,谢谢~

参考

  1. ^rust-match-control-flow-construct https://doc.rust-lang.org/book/ch06-02-match.html#the-match-control-flow-construct
  2. ^rust-patterns-that-bind-to-values https://doc.rust-lang.org/book/ch06-02-match.html#patterns-that-bind-to-values
  3. ^rust-match-option https://doc.rust-lang.org/book/ch06-02-match.html#matching-with-optiont
  4. ^rust-match-are-exhaustive https://doc.rust-lang.org/book/ch06-02-match.html#matches-are-exhaustive
  5. ^rust-catch_all_patterns_and__placeholder https://doc.rust-lang.org/book/ch06-02-match.html#catch-all-patterns-and-the-_-placeholder
  6. ^rust-concise-control-flow-with-if-let https://doc.rust-lang.org/book/ch06-03-if-let.html#concise-control-flow-with-if-let

编辑于 2022-12-09 11:20・IP 属地广东