一、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"),
}

Rust中的模式匹配的更多相关文章

  1. Rust 中的继承与代码复用

    在学习Rust过程中突然想到怎么实现继承,特别是用于代码复用的继承,于是在网上查了查,发现不是那么简单的. C++的继承 首先看看c++中是如何做的. 例如要做一个场景结点的Node类和一个Sprit ...

  2. C# 8.0中的模式匹配

    C# 8.0中的模式匹配相对C# 7.0来说有了进一步的增强,对于如下类: class Point{    public int X { get; }    public int Y { get; } ...

  3. 第74讲:从Spark源码的角度思考Scala中的模式匹配

    今天跟随王老师学习了从源码角度去分析scala中的模式匹配的功能.让我们看看源码中的这一段模式匹配: 从代码中我们可以看到,case RegisterWorker(id,workerHost,.... ...

  4. (数据科学学习手札49)Scala中的模式匹配

    一.简介 Scala中的模式匹配类似Java中的switch语句,且更加稳健,本文就将针对Scala中模式匹配的一些基本实例进行介绍: 二.Scala中的模式匹配 2.1 基本格式 Scala中模式匹 ...

  5. Rust 中的类型转换

    1. as 运算符 as 运算符有点像 C 中的强制类型转换,区别在于,它只能用于原始类型(i32 .i64 .f32 . f64 . u8 . u32 . char 等类型),并且它是安全的. 例 ...

  6. Rust中的RefCell和内部可变性

    RefCell Rust在编译阶段会进行严格的借用规则检查,规则如下: 在任意给定时间,要么只能有一个可变引用,要么只能有多个不可变引用. 引用必须总是有效. 即在编译阶段,当有一个不可变值时,不能可 ...

  7. Rust中的Slices

    这个slice切片,python中有,go中有, 但确实,Rust中最严格. 精彩见如下URL: Rust 程序设计语言(第二版) 简体中文版 · GitBook (Legacy) https://k ...

  8. 刷完欧拉计划中难度系数为5%的所有63道题,我学会了Rust中的哪些知识点?

    我为什么学Rust? 2019年6月18日,Facebook发布了数字货币Libra的技术白皮书,我也第一时间体验了一下它的智能合约编程语言MOVE,发现这个MOVE是用Rust编写的,看来想准确理解 ...

  9. 【翻译】Flink Table Api & SQL —Streaming 概念 —— 表中的模式匹配 Beta版

    本文翻译自官网:Detecting Patterns in Tables Beta  https://ci.apache.org/projects/flink/flink-docs-release-1 ...

  10. 【译】Rust中的array、vector和slice

    原文链接:https://hashrust.com/blog/arrays-vectors-and-slices-in-rust/ 原文标题:Arrays, vectors and slices in ...

随机推荐

  1. 17.6K star!后端接口零代码的神器来了,腾讯开源的ORM库太强了!

    嗨,大家好,我是小华同学,关注我们获得"最新.最全.最优质"开源项目和高效工作学习方法 " 实时零代码.全功能.强安全 ORM 库 后端接口和文档零代码,前端定制返回 J ...

  2. WebAssembly在实际应用中的案例探究

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...

  3. Possible data inputs to DataFrame constructor

    Possible data inputs to DataFrame constructor: import pandas as pd import numpy as np (1) 2D ndarray ...

  4. MySQL设置字符集、排序规则和区分字母大小

    摘要:在MySQL中,设置字符集和排序规则,在查询时区分字母大小写,utf8mb4支持emoji表情,而utf8不支持. 问题综述   在工作中,设置的一些唯一标志字符串和登录密码都是区分大小写的,但 ...

  5. Java遍历Map对象的常见方法

    在Java中遍历Map有不少的方法,我们看一下最常用的方法及其优缺点. 既然Java中的所有map都实现了Map接口,以下方法适用于任何map实现(HashMap, TreeMap, LinkedHa ...

  6. Django Web应用开发实战第七章

    一.ORM框架 Django对各种数据库提供了很好的支持,包括PostgreSQL.MySQL.SQLite和Oracle,且为这些数据库提供了统一API方法,这些API统称为ORM框架. 通过Dja ...

  7. 「Log」2023.8.14 小记

    序幕 起晚了,七点半到校. 跟化竞选手寒暄几句之后就去开电脑. 补周末没写的博客,补落下的题单. 学杜教筛??????不会卷积????? 暂时放弃,学一下扩欧. 写了篇扩欧博客. \(\text{Li ...

  8. k8s service访问偶发超时问题

    问题现象 在某个集群节点上的服务访问service服务:端口,会出现偶发timeout的问题,集群有的节点不会出现访问timeout的问题 问题处理 查看bridge-nf-call-iptables ...

  9. TypeScript实用类型之Omit

    概述 TypeScript Utility Types(实用工具类)包含一系列预定义的类型,用于简化类型操作,善用这些类型可以让我们的代码更加简洁优雅,今天来学习一下Omit类型.Omit类型可以优雅 ...

  10. USB Gadget设备枚举失败的处理方法

    技术背景 我们的板子作为 USB Gadget 设备通过 USB 线接入 USB 主机使用,我们的板子被主机识别为一个 Compsite Device,这个 Compsite Device 是由我们板 ...