Rust中的模式匹配
2023-03-20 14:55:57 时间
一、let模式匹配
在其它一些语言中,let x = 5 之类的语句,仅仅只是赋值语句。但是在rust中,可以换个角度理解,认为5这个值匹配到了x变量。如果觉得有些牵强,可以再来一个示例:
let (a,b)=(1,3);
println!("{},{}",a,b);
上面的示例,表示(1,3)这个元组,匹配(a,b)这一组变量,即a=1, b=3,类似的,struct也可以这样匹配:
struct Point {
x: i32,
y: i32,
}
fn main() {
let p = Point { x: 10, y: 20 };
//模式匹配
let Point { x, y } = p;
//x=10,y=20
println!("x:{},y:{}", x, y);
}
二、match匹配
2.1 匹配简单类型
let x = 1;
match x {
1 => println!("x=1"),
2 => println!("x=2"),
//"_"相当于java中switch的default
_ => println!("default"),
}
let y = 2;
match y {
//匹配1或2
1 | 2 => println!("y=1 or 2"),
_ => println!("default"),
}
let z = 1;
match z {
//匹配1到5
1..=5 => println!("z between 1 and 5"),
_ => println!("default"),
}
let c = 'z';
match c {
//匹配a到z
'a'..='z' => println!("{} in [a-z]", c),
_ => println!("other"),
}
2.2 匹配枚举
以最常用的Option enum为例:
let x = Some(2);
let x_result = match x {
//精确匹配Some(5),x=Some(2),会匹配失败
Some(5) => 5,
_ => -1,
};
println!("{}",x_result);
let x = Some(2);
let x_result = match x {
//只要x有值,就能匹配成功
Some(n) => n,
_ => -1,
};
println!("{}",x_result);
let x = Some(3);
let x_result = match x {
//匹配时,还能指定条件,3>1,下面这行会匹配成功
Some(n) if n>1 => n,
_ => -1,
};
println!("{}",x_result);
输出:
-1 2 3
另外,有些情况下,match还可以用if let语法糖简化代码:
if let Some(v) = Some(5) {
println!("{}", v);
};
//上面的代码,等效于下面这几行:
let w = Some(5);
match w {
Some(n) => {
println!("{}", n)
}
_ => {}
}
有时候,只需要匹配enum类型,不关注值,可以用_来忽略值
let x = Some(4);
let y = Some(5);
match(x,y){
(Some(_),Some(_)) => println!("both are Some Type"),
_ => println!("others")
}
关于“_”,还有一些小技巧,如果只声明1个变量,不使用,rust编译器会警告:
上图的提示,已经给出建议,可以加_,即改成let _x=10,就不会报警了。
另外_在模式匹配中,还可以避免所有权转移:
let s = Some(String::from("hello"));
//由于_不关注值,所以s的所有权不会move到_
if let Some(_) = s{
println!("found a string");
}
//这里能正常输出
println!("s:{:?}",s);
但如果,把Some(_),换成其它方式,比如
不仅仅是系统自带的enum,开发人员自定义的enum也一样可以进行匹配:
enum Order {
New { order_id: i32 },
}
let o1 = Order::New { order_id: 1 };
match o1 {
Order::New { order_id: x } if x >= 0 && x <= 10 => {
println!("order_id:{} between 0 and 10", x)
}
_ => {}
}
//与上面的写法等效(注意多了1个@符号,表示把匹配到的值,赋值到@修饰的变量n里)
match o1 {
Order::New {
order_id: n @ 1..=10,
} => println!("order_id:{} between 0 and 10", n),
_ => {}
}
2.3 匹配元组
let t = (1, 2,3);
match t {
//仅匹配第1项,其它元素忽略
(1, ..) => println!("first item is 1"),
_ => println!("default"),
}
let t = (2, 3);
match t {
//匹配第1项,第2项放到变量n里
(1, n) => println!("{},{}", 1, n),
_ => println!("default"),
}
let t = (1, 2, 3, 4, 5, 6);
match t {
//匹配第1项与最后1项
(1, .., 6) => println!("first:1,last:6"),
_ => println!("others"),
}
2.4 匹配struct
struct Point {
x: i32,
y: i32,
}
let p = Point { x: 10, y: 20 };
match p {
Point { x: 10, y: 20 } => println!("完全匹配!"),
Point { x: 5, y } => println!("要求x匹配5,y无所谓"),
Point { x, y } => println!("p中的x,y匹配到{},{}", x, y),
_ => println!("others"),
}
相关文章
- 金融服务领域的大数据:即时分析
- 影响大数据、机器学习和人工智能未来发展的8个因素
- 从0开始构建一个属于你自己的PHP框架
- 如何将Hadoop集成到工作流程中?这6个优秀实践必看
- SEO公司使用大数据优化其模型的5种方法
- 关于Web Workers你需要了解的七件事
- 深入理解HTTPS原理、过程与实践
- 增强分析:数据和分析的未来
- PHP协程实现过程详解
- AI专家:大数据知识图谱——实战经验总结
- 关于PHP的错误机制总结
- 利用数据分析量化协同过滤算法的两大常见难题
- 怎么做大数据工作流调度系统?大厂架构师一语点破!
- 2019大数据处理必备的十大工具,从Linux到架构师必修
- OpenCV中的KMeans算法介绍与应用
- 教大家如果搭建一套phpstorm+wamp+xdebug调试PHP的环境
- CentOS下三种PHP拓展安装方法
- Go语言HTTP Server源码分析
- Go语言HTTP Server源码分析
- 2017年4月编程语言排行榜:Hack首次进入前五十