前言
我认为Enum在Rust里是一个极其重要的feature。它比大部分语言的Enum的强大多了。它不但可以表示一组常量,还可以表示一组类型。
Enum的特性
表示一组常量
enum IpAddrKind { V4, V6, }
这样定义了有以上2个值的枚举。
表示一组类型
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
注意其中每个类型里面的数据类型都可以是不一样的。
Enum的用途
虽然enum支持的特性,很简单就介绍完了。但是基于enum能做的事情很多。
Option
这是Option的定义
enum Option<T> {
None,
Some(T),
}
在Rust里,声明一种类型的时候,默认是非空的。把一种类型用Option
包起来,可以表示可空的某个类型。
开发者在遇到可能为空的类型的值的时候,必须考虑它为空值的情形,否则无法通过编译,这样减少了错误。
而且,Rust标准库给Option
提供了一大堆方法,帮助开发者处理可能为空的值。
match
match和enum组合起来,可以很方便地判断一个值的类型。对不同的类型的值,做不同的操作。
#[derive(Debug)] // so we can inspect the state in a minute
enum UsState {
Alabama,
Alaska,
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => {
println!("State quarter from {:?}!", state);
25
}
}
}
option常常和match结合起来使用。用来判断一个值为空还是非空,进行不同的操作。
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
}
}
相对于使用if else,match的好处是编译器会判断match的有没有覆盖所有可能的情况。当然,为了简单,可以给出一个用来兜底的分支。
如果只对某一个类型有兴趣,那就没必要使用match了,用 if let 代替即可。
总结
Enums 与 Pattern Matching结合可以很方便地对一个值进行类型的判断。相对于使用instanceof + if else,它们的好处是
- 语法更加简洁
- 判断类型更容易实现不重复也不漏掉。