昨天我们学了enum
以及Option
今天我们继续往下学
match
控制流结构其实我们之前就用过了,在第二天写一个猜数游戏。
在比对数值的时候就用了这个match
模式匹配,匹配比较的变体(variant
),有大于、小于以及等于三种变体。
match
可以用于字面量、 变量、通配符等其他各种东西匹配,是非常强大的功能。
我们来看下一个例子
我们先是声明了一个枚举Coin
,然后又声明了一个函数value_in_cents
,参数是Coin
也就是枚举类型,返回一个u8
的数据。
之前有一个点我们忘了说了,枚举的变体是可以不用设置默认值的
我们跑下代码
我们先是声明了一个Coin
的变体Penny
然后match
了Coin
这个枚举的所有变体(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
这样你就能专注于3
和7
的场景,其他场景统一处理。
另外,如果我们不想处理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
等。
明天居家,隔壁老哥阳了~
如果觉得对你用帮助,麻烦点个赞,谢谢~
编辑于 2022-12-09 11:20・IP 属地广东