Rust-枚举和Match匹配
系列文章
在上一篇文章里,我们探讨了Rust中的一个重要概念——引用和借用。在这篇文章中,我们将继续探讨本人在通过Rustling学习Rust中遇到的第二个问题——枚举(Enum)和模式匹配(Match)
枚举(Enum)
枚举通过关键字enum来声明,通过enum关键字我们可以声明一个指定的枚举类型。
比如在Rust圣经中的一个例子:
1 | enum PokerSuit{ |
这里我们声明了一个枚举类型PockerSuit,其中包含了4种枚举值:Clubs,Spades,Diamonds,Hearts。之后,我们便可以使用它们了,比如我们可以创建两个PockerSuit类型的成员实例:
1 | let heart = PokerSuit::Heart; |
之后我们便可以给枚举类型的成员实例附上值了,这可比golang好用多了:
1 | let d12 = PockerSuit::Diamonds(12); |
当然,我们可不满足于此,对于同一枚举类型的不同的枚举成员,我们还可以给他关联上不同的数据类型:
1 | enum Message{ |
我们甚至可以关联结构体或其他枚举类型:
1 | //enum |
1 | //struct |
真是强而有力,强而有力啊
Match——匹配
当我们成功声明了一个枚举类型之后可能会遇到一个问题:如何处理同一枚举类型下的不同枚举值?它们可能对应的是不同的数据类型。
幸运的是,Rust给我们提供了模式匹配来方便我们对不同的枚举值进行处理,本文我们先探讨第一种模式匹配方法——match
如何使用
我们首先来看看match的通用形式
1 | match target { |
要注意:
match的每一个分支都必须是一个表达式,且所有分支的表达式最终返回值的类型必须相同。match的匹配必须要穷举出所有可能,这里使用_来匹配除了模式1和模式2以外的其他所有情况- 匹配的模式可以使用
|来表示逻辑运算中的或,从而匹配多种模式,例如模式3 | 模式4 => 表达式foo,
注意!这里只能使用|,不能使用||、&&、!等逻辑运算符,match的模式匹配中每个匹配臂(arm)的模式必须是独立的,如果想要更复杂的匹配方式,需要添加匹配守卫(Pattern guard),来进一步改进匹配标准,关于匹配守卫,我们应该会在后面的文章中进一步探讨。
这里展示一个简单的例子:
1 | enum PokerSuit{ |
使用match表达式赋值
match 本身也是一个表达式,因此可以用它来赋值:
1 | //偷了一个Rust圣经的例子 |
因为这里匹配到_分支,所以将"::1" 赋值给了ip_str。
模式绑定
终于来到了重头戏(这篇文章就是为了这个而生的),match的一个重要功能就是从模式中取出绑定的值,例如我们在枚举中举的一个例子:
1 |
|
穷尽匹配
简单来说,如果你在match中没有列出所有可能的匹配情况,cargo会报错 Cargo:写的什么垃圾代码,你给我去屎吧
_通配符
当我们不想在匹配时列出所有值的时候,可以使用 Rust 提供的一个特殊模式_通配符,比如我们的函数只关心PokerSuit中的红牌:
1 | fn show_me_red(suit:PokerSuit) -> String{ |
当然,除了_,我们也可以用其他变量来承载其他情况:
1 | fn show_me_red(suit:PokerSuit) -> String{ |
总结
Rust提供了强大的枚举和match匹配来使得我们的代码更加简洁美观,让我们可以摆脱丑陋的if else,在后面的文章里(如果有的话),我们会进一步探讨其他的模式匹配方法,以及之前提到的匹配守卫(Pattern guard)。
部分内容引用自Rust语言圣经(Rust Course)


