rust从入门到精通09-模式解构

author author     2022-12-04     443

关键词:

"Pattern Destructure" 是 Rust 中一个重要且实用的设计。通常翻译为 “模式解构”。

Destructure 单词翻译为把原来的结构肢解为单独的、原始的部分。

下面我们举例说明什么是模式解构:

fn main() 
let tul = (1,"a",false);
let (head,center,tail) = tul;
println!("",head);//1
println!("",center);//a
println!("",tail);//false

第2行代码是构造;第3行代码是拆解,产生了三个新的变量。

Rust 的模式解构不仅出现在 let 语句中,还可以出现在 match、if let、while let、函数调用、闭包调用等情景中。

1、match

1.1 用于匹配多种取值
rustenum Direction
East,
West,
South,
North,

fn print(x:Direction)
match x
Direction::East =>
println!("East");

Direction::West =>
println!("West");

Direction::South =>
println!("South");

Direction::North =>
println!("North");


当一个类型有多种取值时,特别适合适用 match 表达式。可以等价于 if-else

1.2 必须匹配到每个分支exhaustive

exhuastive:彻底的,详尽的

对应到 match 表达式上,Rust 要求 match 需要对所有的情况做彻底的,无遗漏的匹配。比如对于上面的例子,我们删除一个匹配分支(East)

注意:编译器会保证 match 所有分支合起来一定覆盖了所有的情况,但是不保证各个分支重复的问题。

enum Direction
East,
West,
South,
North,

fn print(x:Direction)
match x
Direction::West =>
println!("West");

Direction::South =>
println!("South");

Direction::North =>
println!("North");



fn main()
print(Direction::West);

编译就会报错:

Rust从入门到精通09-模式解构_下划线

1.3 一个分支匹配多种类型 |

我们可以通过 | 在一个分支匹配多种情况;

enum Direction
East,
West,
South,
North,

fn print(x:Direction)
match x
Direction::East =>
println!("East");

Direction::West | Direction::South | Direction::North=>
println!("Other");


1.3 通配模式和 _ 占位符

有时候,我们并不知道到底有多少种匹配情况,这时候可能需要一个类似通配符,来匹配所有没有考虑的情况,从而避免编译失败。

fn print(x:Direction)
match x
Direction::West =>
println!("West");

Direction::South =>
println!("South");

other =>
println!("orther");



上面代码前面两个分支我们匹配了 West 和 South,剩下两个分支我们直接定义了一个名为 other 的变量(这个变量可以任意命名),它将匹配所有未被特殊列出来的值。

需要注意:我们必须将通配分支放在最后,因为模式是按顺序匹配的。如果我们在通配分支后添加其他分支,Rust 将会警告我们,因为此后的分支永远不会被匹配到。

除此之外,Rust 还推出了"_" 占位符来匹配所有情况。

enum Direction
East,
West,
South,
North,

fn print(x:Direction)
match x
Direction::East =>
println!("East");

_ =>
println!("other");


1.4 忽略匹配占位符 _

下划线除了用作 match 表达式中的分支额外匹配之外,还可以用来表示一个占位符,表示虽然匹配到了,但是忽略掉。

struct P(i32,i32,i32);
fn add(p:P) -> i32
let P(x,_,y) = p;
x+y

fn main()
let p = P(1,2,3);
println!("",add(p));//4

我们只想求元祖结构体P的第一个和末尾数据之和,所以中间的数据可以通过_ 忽略掉。

1.5 match guards 匹配看守

match 和 if 配合一起使用。

enum OptionalInt
Value(i32),
Missing,

fn match_if(op:OptionalInt)
match op
OptionalInt::Value(i) if i > 10 => println!("big int")
OptionalInt::Missing => println!("not int")

但是上面这段代码会编译错误,提示没有覆盖所有的情况。(如果移除 if 条件,是正常编译的)

Rust从入门到精通09-模式解构_下划线_02

那么如何修改这个问题呢?我们增加 if 匹配条件看看:

fn match_if(op:OptionalInt)
match op
OptionalInt::Value(i) if i > 10 => println!("big int"),
OptionalInt::Value(i) if i<= 10 => println!("get int"),
OptionalInt::Missing => println!("not int"),

发现还是编译失败

我们已经通过 if 覆盖了所有的情况,但是还是不能编译通过,这其实也是 rust 编译器目前无法做到的,它毕竟不是一个完整的数学解析器。

这种情况下,我们加个下划线匹配就可以了。

fn match_if(op:OptionalInt)
match op
OptionalInt::Value(i) if i > 10 => println!("big int"),
OptionalInt::Value(i) if i<= 10 => println!("get int"),
_ => println!("没有特殊意义"),
OptionalInt::Missing => println!("not int"),

2、if-let

比如有一个类型为 Option 的变量 val,我们要取出里面的值。

①、使用match表达式

fn getOptionVal(str:Option<String>) -> String
match str
Some(x) => x,
None => panic!("called `Option::unwrap()` on a `None` value")



fn main()
let val = Some("ab".into());
println!("",getOptionVal(val));//ab

②、if 表达式

fn getOptionVal(str:Option<String>) -> String
if str.is_some()
return str.unwrap();

panic!("called `Option::unwrap()` on a `None` value")

fn main()
let val = Some("ab".into());

println!("",getOptionVal(val));//ab

③、if-let

fn getOptionVal(str:Option<String>) -> String
if let Some(x) = str
return x;

panic!("called `Option::unwrap()` on a `None` value")

fn main()
let val = Some("ab".into());
println!("",getOptionVal(val));//ab

第二种方法(if 表达式)取值分两步,第一步调用 is_some()判断,第二步调用unwrap()取值;

而if-let 看上去就简洁很多,但是和 if 表达式相比并没有效率上的差别,只是rust提供的一个语法糖。

es6从入门到精通#07:解构赋值(代码片段)

说明ES6从入门到精通系列(全23讲)学习笔记。解构赋值解构赋值是对赋值运算符的一种拓展,它针对数组和对象来进行操作。优点:代码书写上简单易读letman= name:"kaimo", value:313//es5letname=man.name;letvalue... 查看详情

rust从入门到精通04-数据类型

Rust是静态类型(staticallytyped)语言,也就是说在编译时就必须知道所有变量的类型。在Rust中,每一个值都属于某一个数据类型(datatype),分为两大类:①、标量(scalar):整型、浮点型、布尔类型、字符类型②、复合(compound... 查看详情

rust从入门到精通12-集合

Rust标准库中还提供了一系列被称为集合(collections)的数据结构,类似于JDK中​​java.util​​包下面的一些集合类(List/Set/Map等),这类集合指向的数据是存储在堆上,意味着数据的数量不必在编译期就已知,并且还能随着程序... 查看详情

rust从入门到精通10-所有权

在介绍rust所有权时,我们先介绍内存管理的一些基础概念。1、堆和栈一个进程在执行的时候,它所占用的内存虚拟空间一般被分割为好几个区域,我们称为”段“(Segment)。常见的几个段如下:①、代码段:编译后的机器码存... 查看详情

oracle从入门到精通系列讲解-总目录(代码片段)

总目录欢迎大家来到Lucifer三思而后行的《Oracle从入门到精通系列》,开始前博主先列出Oracle学习的大纲,同时这也可以作为大家学习Oracle的参考。下面蓝字都是传送门,点击进入即可:学前必读Oracle从入门到精通... 查看详情

rust从入门到精通05-语句和表达式

1、语句和表达式语句和表达式是Rust语言实现逻辑控制的基本单元。在Rust程序里面,语句(Statement)是执行一些操作但不返回的指令,表达式(Expressions)计算并产生一个值。表达式可以是语句的一部分,反过来,语句也可以是... 查看详情

es6从入门到精通系列学习笔记23篇(完结)

说明ES6从入门到精通系列(全23讲)学习笔记。可以自行搜索B站,有小马哥的视频学习。目录ES6从入门到精通#01:ES6介绍ES6从入门到精通#02:let和const命令ES6从入门到精通#03:模板字符串ES6从入门到精通#04&... 查看详情

wpfmvvm从入门到精通4:命令和事件(代码片段)

原文:WPFMVVM从入门到精通4:命令和事件 ?WPFMVVM从入门到精通1:MVVM模式简介WPFMVVM从入门到精通2:实现一个登录窗口WPFMVVM从入门到精通3:数据绑定WPFMVVM从入门到精通4:命令和事件WPFMVVM从入门到精通5:PasswordBox的... 查看详情

wpfmvvm从入门到精通3:数据绑定

原文:WPFMVVM从入门到精通3:数据绑定 ?WPFMVVM从入门到精通1:MVVM模式简介WPFMVVM从入门到精通2:实现一个登录窗口WPFMVVM从入门到精通3:数据绑定WPFMVVM从入门到精通4:命令和事件WPFMVVM从入门到精通5:PasswordBox的绑... 查看详情

牛逼!java从入门到精通,超全汇总版

文章目录Java基础HeadFirstJavaJava核心技术卷一Java编程思想设计模式HeadFirst设计模式图解设计模式设计模式重学Java设计模式Java进阶Java并发编程实战Java并发编程艺术Java并发编程之美图解Java多线程设计模式JVM深入理解Java虚拟机Java虚... 查看详情

es6从入门到精通#09:symbol类型(代码片段)

说明ES6从入门到精通系列(全23讲)学习笔记。Symbol类型原始数据类型:Symbol,它表示是独一无二的值。最大的用途:用来定义对象的私有变量。constkaimo=Symbol("kaimo");constkaimo2=Symbol("kaimo");conso... 查看详情

java设计模式从精通到入门四简单工厂方法模式

简单工厂方法模式属于23中设计模式中创建型类型。核心思想:工厂提供创建对象的接口,由子类决定实例化哪一个子类。来源?设计模式之禅中的例子,女娲造人,通过八卦炉来进行造人,没有烧熟的为白人,烧太熟的为黑人,... 查看详情

wpfmvvm从入门到精通8:数据验证(代码片段)

原文:WPFMVVM从入门到精通8:数据验证 WPFMVVM从入门到精通1:MVVM模式简介WPFMVVM从入门到精通2:实现一个登录窗口WPFMVVM从入门到精通3:数据绑定WPFMVVM从入门到精通4:命令和事件WPFMVVM从入门到精通5:PasswordBox的绑... 查看详情

wpfmvvm从入门到精通7:关闭窗口和打开新窗口

原文:WPFMVVM从入门到精通7:关闭窗口和打开新窗口 WPFMVVM从入门到精通1:MVVM模式简介WPFMVVM从入门到精通2:实现一个登录窗口WPFMVVM从入门到精通3:数据绑定WPFMVVM从入门到精通4:命令和事件WPFMVVM从入门到精通5:... 查看详情

json从入门到精通(全)(代码片段)

目录前言1.入门知识2.结合JavaScript2.1eval函数2.2parse()和stringify()函数3.结合ajax4.结合jquery5.结合springmvc前言这篇文章参考了狂神对json的理解,以及融合了自已对json数据的理解做出的笔记【狂神说Java】一小时掌握JSON在学习这部... 查看详情

es6从入门到精通系列学习笔记23篇(完结)

说明ES6从入门到精通系列(全23讲)学习笔记。可以自行搜索B站,有小马哥的视频学习。目录ES6从入门到精通#01:ES6介绍ES6从入门到精通#02:let和const命令ES6从入门到精通#03:模板字符串ES6从入门到精通#04&... 查看详情

android基础教程——从入门到精通(上)(代码片段)

...是上部分,下部分链接为:Android基础教程——从入门到精通(下)源视频教程并没有录制全,本文还补充了Service和网络通信的内容文章介绍详细,示例代码丰富,相信跟着本教程可以打下很好的Android... 查看详情

mysql数据库基础从入门到精通

总结MySQL数据库基础,包含一些面试题及案例。下面链接分章教程,点击查看↓↓↓↓↓↓↓↓↓↓MySQL(一)数据库操作MySQL(二)DML语言MySQL(三)Select查询详解及常用函数MySQL(四)Select... 查看详情