一、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. 【经验】Win11的Ubuntu虚拟机启动虚拟化|此平台不支持虚拟化的 Intel VT-x/EPT(方案汇总+自己的解决方案)

    我开虚拟化是为了在虚拟机中运行VirtualBox,如果不开CPU虚拟化,会报错VBoxManage error: VT-x is not available (VERR_VMX_NO_VMX). 文 ...

  2. vue3 基础-传送门 teleport

    之前介绍了一波混入 mixin 和 自定义指令 directive 其基本作用就是为了在 vue 中实现代码的复用. 而本篇介绍的是 vue3 的一个新特性叫做传送门. 一听这个名字是不是就感觉特别科 ...

  3. 一文玩转NGINX(对于NGINX,你真的了解吗?)

    前言 nginx [engine x] 是一个 HTTP 和反向代理服务器, 邮件代理服务器, 和一个通用的 TCP/UDP 代理服务器, 最初由 Igor Sysoev. 运行了很久 在许多负载重的 ...

  4. 网络编程:使用poll单线程处理所有I/O事件

    事件驱动模型 事件驱动的好处:占用资源少,效率高,可扩展性强,是支持高性能高并发的不二之选. 事件驱动模型也叫作反应堆模型(reactor),或者是Event loop模型,该模型的核心有两点: 1. ...

  5. CSS 之overflow属性简结

    CSS的overflow 属性用来处理一个元素的尺寸超出其容器尺寸的情况.当一个元素包含的内容超粗自身的大小时,就会发生内容溢出,这种情况,可以对内容进行"裁剪",只让一部分内容可 ...

  6. C#之Stream和IO

    C#之Stream和IO public class test { public int aa = 100; public string testStr = "test"; publ ...

  7. Vmware workstation安装部署微软WSUS服务应用系统

    简介 WSUS全称‌Windows Server Update Services‌,是微软开发的免费服务器角色,用于在企业内网中集中管理Windows系统及微软产品的更新分发.其前身为Windows ...

  8. 用鼠标画圆点(java GUI)

    话不多说,先看效果 当然你也可以发挥脑洞绘制更更棒的 源码如下: package javaBasic; import java.awt.*; import java.awt.event.*; impo ...

  9. Web前端入门第 60 问:JavaScript 各种数组定义与数组取值方法

    数组可以算是程序里面最常用的数据结构了,但凡网页上任何一个列表数据,基本都是以数组的形式存在,像表格.banner图.菜单列表.商品列表,分类列表等等,在前端领域都是以数组处理. 数组的定义 JS 的 ...

  10. 宝塔面板部署vue项目(MyAuthWeb)

    前言 在前文中,部署好后端了,就可以开始部署前端了,本文使用常见的宝塔面板演示 宝塔面板部署vue项目一般有两种方式,一种是build成纯静态,一种是直接部署node项目 本文以TianYe负责维护的 ...