枚举
枚举允许我们列举所有可能的值来定义一个类型。
定义枚举
枚举里面的字段被称为**变体。
enum IP{
V4,
V6,
}
枚举值
let fout = IP::V4
将枚举传入函数
enum IP{
V4,
V6,
}
fn main(){
let four = IP::V4;
route(four);
route(IP::V6);
}
// 签名接收一个枚举
fn route(ipKind: IP){}
将数据附加到枚举的变体中
rust可以不通过结构体struct来为枚举赋值,可以直接赋值。
enum IP {
V4(u8, u8, u8, u8),
V6(String),
}
fn main(){
let localhostV4 = IP::V4(127, 0, 0, 1);
let localhostV6 = IP::V6(String::from("::1"));
}
可以在变体中嵌入任意类型的数据。
为枚举定义方法
使用 impl
impl SendMessage{
fn call(&self){}
}
...
// 调用
let action = SendMessage::Quit;
action.call();
...
Option枚举
定义在标准库中,在Prelude(预导入模块)中。某个值(某种类型)可能存在或不存在的情况。
rust没有null,为了安全性。
但是rust有null的概念:因某种原因而变为无效或缺失的值。
enum Option<T> { Some(T), None}
T是泛型枚举。
因为是预导入的枚举,所以可以直接使用这个枚举里的变体。
fn main(){
let someNumber = Some(5);
let someString = Some("hi");
// 这个变量是没有有效的值,并且要主动声明是i32类型
let unknow: Option<i32> = None;
}
Option
eg: let x: i8 = 5; let y: Option<i32> = Some(5);
如果需要使用则需要转换,避免了一个问题:假设想使用这个值,但是这个值却为none。
match
允许一个值与一系列的模式进行匹配,并执行匹配的模式对应的代码。模式可以是字面值,变量名或通配符等。
有点类似python的反射,getattr,hasattr。或者其他语言的switch case。
enum Money {
CNY,
HKD,
JPY,
USD,
}
fn setMoney(money: Money) -> u8 {
match money {
Money::CNY => 500,
Money::HKD => 1000,
Money::JPY => 1500,
Money::USD => {
print!("change USD!");
100
},
}
}
fn main() {}
match 会将传进来的参数与设置的变体依次比较,成功则返回。复杂的代码就多加个花括号。
匹配Option
match 里写 None,和Some(i)就行,i代表传入Some中的值。
match表达式必须穷举所有的表达式,就是匹配的枚举里的所有变体都要写进去。当变体比较多的时候可以使用 _ 通配符代替。
_ => ()
通配符要放在最后面。
match 中传参绑定
enum Money {
CNY,
HKD,
JPY,
USD(Bank),
}
#[derive(Debug)]
enum Bank {
HSBC,
BOC,
}
fn setMoney(money: Money) -> u16 {
match money {
Money::CNY => 500,
Money::HKD => 1000,
Money::JPY => 1500,
Money::USD(Bank) => {
print!("change USD in {:?}!", Bank);
100
},
}
}
fn main() {
let gotoUSA = Money::USD(Bank::BOC);
setMoney(gotoUSA);
}
if let
简单的控制流,只关心一种匹配而忽略其他匹配。
if let 条件 = v {print!("{}", v)}
也可以搭配else
fn main() {
let v = Some(2);
if let Some(2) = v {
print!("{:?}", v);
} else {
print!("others");
}
}
总结
- Option
可能有值也可能为空,这样做是为了安全,想使用时就需要转换。反过来说,如果这个值不是option ,那这个值一定不是为空的。 类似强制做判断是否为空。