模式匹配是一个强大的功能。Rust中的模式匹配不仅本身执行效率高,使用恰当还能让代码变得更加简洁易读,更利于后续扩展和维护。
match
是rust
中用于模式匹配的关键字。接下来分别以枚举类型和字符串常量类型进行代码示例。
模式匹配(枚举类型)
// 定义一个枚举类型
enum Gender {
Male = 1,
Female = 2,
}
fn gender_str(g: Gender) -> String {
match g {
Gender::Male => "Male".to_owned(),
Gender::Female => "Female".to_owned(),
}
}
println!("{:?}", gender_str(Gender::Male));//"Male"
println!("{:?}", gender_str(Gender::Female));//"Female"
枚举类型占用的字节数,取决于其中最宽(占用字节数最大)的成员。
如果修改
Gender
定义中Female=2000
,那么Gender
类型将会占用2个字节;如果修改
Gender
定义中Female=65539
,那么Gender
类型将会占用4个字节;println!(“size: {}”, std::mem::size_of::());//1
模式匹配(字符串常量)
fn binary_op(x: i32, y: i32, op: &str) -> i32 {
match op {
"+" => {
x + y
}
"-" => {
x - y
}
_ => {
panic!("Unsupported binary_op: {}", op);
}
}
}
println!("{}", binary_op(1,2, "+"));//3
println!("{}", binary_op(1,2, "-"));//-1
println!("{}", binary_op(1,2, "*"));//panic
其中_
占位符用于匹配其他所有情况。
pub fn min_operations(logs: Vec<String>) -> i32 {
let mut depth = 0;
for x in logs.iter() {
match x.as_str() {
"./" => continue,
"../" => if depth > 0 { depth -= 1; },
_ => depth += 1
}
}
depth
}
带参数(if let)的模式匹配
看标准库中的Option<T>
是一个带泛型参数T的枚举,代表一个T类型的值,或者None。
pub enum Option<T> {
/// No value
None,
/// Some value `T`
Some(T),
}
let x: Option<i32> = None;
let y: Option<i32> = Some(100);
println!("{:?}", x);//None
println!("{:?}", y);//Some(100)
// 带参数的模式匹配
if let Some(xval) = y {
println!("Some(x={})", xval);//Some(x=100)
}
带条件(guard)的模式匹配
let fraction = (10, 20);
// 带条件判断(guard)的match
// if y!=0
match fraction {
(x, y) if y!=0 => {
println!("{x}/{y}") //10/20
}
_ => ()
}
open range模式匹配
1.55版本新增了open range pattern。
let score: usize = 60;
let score_desc:&str = match score {
0..=59 => "D",
60..=74 => "C",
75..=89 => "B",
90..=100 => "A",
_ => unreachable!(),
};
println!("score: {}, score_desc:{}", score, score_desc);