1. 枚举
1. 什么是枚举?
枚举是一种数据类型,其能聚合不同成员,你可以通过枚举去匹配成员生成对应成员数据类型的变量。
2. 定义枚举
对于已知所有可能的抽象对象,如Ip地址,通过创建汇枚举以汇聚其所有可能情况。
rust
enum IP{
V4,
V6
}
//枚举实例
let A = IP::V4;
//虽然能创建枚举实例,但却没有实际数据类型,可配合结构体实现类型+值
struct IpInfo{
ip_kind:IP::V4,
ip_address:String
}
//可以创建带有具体值和种类的IP实例了
let personal = IpInfo{
ip_kind:IP::V4,
ip_address:String::from("192.168.11.35")
}如何在定义枚举时直接关联成员的数据类型?枚举允许直接指定其成员的数据类型,可以将任意类型的数据放入枚举成员中,甚至包括另一个枚举类型。
rust
#![allow(unused)]
fn main() {
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
//对于上面的IP实例可以作如下修改
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
}注意:
枚举成员不可以和相同基本数据类型数据进行计算。
rustenum Matrix{ x(u32) } fn main(){ let A = 8; let B = Matrix::x(10); let C = A * B ;//这里A和B不能进行运算 }
3. Option 枚举
Option枚举是标准库定义的枚举,标识一个变量要么有具体值要么什么也没有。其在标准库的定义如下:
rust
#![allow(unused)]
fn main() {
enum <T> {
Some(T),
None,
}
}实际使用无需写 ::Some(xxx),只需要Some(T)即可。在对 <T> 进行 T 的运算之前必须将其转换为 T
2. match
match是一个强大的控制流运算符,使用它将一个值与一系列模式去匹配,并根据相匹配的模式执行相应代码。模式可由字面量、变量、通配符和许多其他内容构成。
Rust 中的match是穷举式的(exhaustive):必须穷举到最后的可能性来使代码有效。
1. 模式匹配Option<T>
当match到对应类型的数据时,为了满足穷举机制,None的情况要始终被覆盖:
rust
//模拟实现一个匹配Option<i32>的示例
fn plus(x:<i32>) -> <i32>{
match x {
None => None,
Some(i) => Some(i+1)
}
}
fn main(){
let n = plus(None);
let six = plus(Some(5))
}2. 通配符和_占位符
在实际应用中,如果需要处理某些特定值之外的所有值的情况,可以使用通配符来处理。通配符不是某个具体的符号,而是一个自定义的无实际意义的“形参”。
rust
//模拟在飞行棋游戏中,掷骰子,设定1和6为特殊点数,其他点数则前进对应格数
use rand::Rng;
...
fn toe(x:u32){
match x {
1 => punish(),
6 => rewards(),
other => move(other)
//当到其他点数时,要求重投掷
//_ => roll_again()
}
}
fn main(){
let secret_number = rand::thread_rng().gen_range(1..7);
toe(secret_number)
}注意:
通配符会获取模式的值、占位符则不会,因此占位符适合在不需要获取到模式值的情况使用。
3. if let简单控制流
if let是对match的一种简化,用于只想处理某一个模式的情况,match需要写通配符或者占位符实现,但依旧要对其余情况做处理,而使用if let则完全不用考虑其他模式。
rust
//比如想匹配一个Option u8类型
//match实现
#![allow(unused)]
fn main() {
let some_u8_value = Some(0u8);
match some_u8_value {
Some(3) => println!("three"),
_ => (),
}
}
//if let实现
#![allow(unused)]
fn main() {
let some_u8_value = Some(0u8);
if let Some(3) = some_u8_value {
println!("three");
}
}此外,可以在 if let 中包含一个 else。else 块中的代码与 match 表达式中的占位符 _ 分支块中的代码相同。
rust
#![allow(unused)]
fn main() {
#[derive(Debug)]
enum UsState {
Alabama,
Alaska,
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
let coin = Coin::Penny;
let mut count = 0;
//match实现穷尽模式
match coin {
Coin::Quarter(state) => println!("State quarter from {:?}!", state),
_ => count += 1,
}
//if let实现
if let Coin::Quarter(state) = coin {
println!("State quarter from {:?}!", state);
} else {
count += 1;
}
}