news 2026/2/12 18:32:16

rust中常见数据类型 match 匹配用法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
rust中常见数据类型 match 匹配用法

模式匹配,增强版的 switch

  1. 可以匹配各种类型(不只是整数或字符串)
  2. 能解构复杂的数据结构(比如元组、枚举、结构体)
  3. 是表达式,返回值
  4. 要求穷尽所有可能(不会漏掉情况)

语法规则

match 要匹配的值 { 模式1 => {...}, 模式2 => {...}, 模式3 => {...}, ... }

✅ 整数匹配

#[test] fn match_script() { let number = 5; match number { 1 => println!("1111"), 2 => println!("2222"), 3..=7 => println!("闭区间"), // 3 4 5 6 7 9..13 => println!("半开区间"), // 9 10 11 12 _ => println!("default"), // 通配符,匹配其余所有 } }

_表示通配符,匹配其余所有,3..=73..7区间写法

✅ 字符切片匹配

#[test] fn match_script() { let input = "yes"; // &str 可拷贝类型 match input { "yes" => println!("Affirmative!"), "no" => println!("Negative!"), _ => println!("Unknown response"), } println!("input: {}", input); // 可正常输出 }

和整数匹配一样,匹配完所有权也还在

✅ 枚举匹配

#[derive(Debug)] enum Rgb { Red, Green, Blue, } #[test] fn match_script() { let color = Rgb::Red; match color { Rgb::Red => println!("Red"), Rgb::Green => println!("Green"), Rgb::Blue => println!("Blue"), } }

这里会打印Red,match要求匹配的值每个可能的case都要实现,硬性规定

这样写会报错

let color = Rgb::Red; match color { Rgb::Red => println!("Red"), Rgb::Green => println!("Green"), }
✅ Option 枚举匹配

业务场景: 通常用于获取内容,比如数据库查询只会有两个结果,一个是值内容,一个是无内容

#[test] fn match_script() { let maybe_value: Option<i32> = Some(41); match maybe_value { Some(x) => println!("Got a value: {}", x), None => println!("No value"), } let maybe_none: Option<i32> = None; match maybe_none { Some(x) => println!("Got a value: {}", x), None => println!("No value"), } }

output

Got a value: 41 No value

枚举匹配,会将变体的值带入,例如Some(x) => println!("Got a value: {}", x),匹配上就是Some(41), => 后面的相当于函数实现,x 相当于实参

✅ Result 枚举匹配

业务场景: 通常用于结果资源,比如数据库连接只会有两个结果,一个是连接成功,一个是连接错误

use std::fs::File; #[test] fn match_script() { let maybe_value: Result<&str, &str> = Ok("successful"); match maybe_value { Ok(x) => println!("Got a value: {}", x), Err(e) => println!("Error : {}", e), } // 打开文件 match File::open("Cargo.lock") { Ok(_file) => println!("Opened file successfully"), Err(error) => println!("Error opening file: {}", error), } }

output

Got a value: successful Opened file successfully
  1. Result 和 Option 枚举匹配用法一样
  2. _file表示这个变量暂时没用到

✅ 结构形式匹配

✅ 解构元组
#[test] fn match_script() { let maybe_tuple = (0, "msg", "data"); match maybe_tuple { (0, x, "data") => { println!("tuple.code: {:?}", x); } (0, "msg", "data_list") => { println!("tuple is {:?}", maybe_tuple); } (0, x, y) => println!("tuple.msg: {:?} data: {:?} ", x, y), _ => println!("tuple is not match"), } }

output

tuple.code: "msg"
  1. match要求匹配的各种可能性都要实现,如果不想写那么多,最后加一个_通配默认实现即可
  2. 匹配中也支持具体值匹配,例如(0, "msg", "data_list")(0, x, y)都是可以匹配上的
  3. 匹配参数支持混合,(0, x, "data")(z, x, y)
  4. 最终输出的是(0, x, "data")分支,而不是(0, x, y),优先匹配上面的代码

还是原来的代码,现在换个case顺序

#[test] fn match_script() { let maybe_tuple = (0, "msg", "data"); match maybe_tuple { (0, x, y) => println!("tuple.msg: {:?} data: {:?} ", x, y), (0, x, "data") => { println!("tuple.code: {:?}", x); } (0, "msg", "data_list") => { println!("tuple is {:?}", maybe_tuple); } _ => println!("tuple is not match"), } }

这种编译就通不过了,第一个 case 已经涵盖了第二个 case,代码冗余了

✅ 解构结构体
struct Point { x: i32, y: i32, } #[test] fn match_script() { let p = Point { x: 10, y: 10 }; match p { Point { x: 0, y } => println!("match Point.y: {}", y), Point { x, y } => println!("Point: ({}, {})", x, y), } }

output
Point: (10, 10)

这里我的Point { x, y }已经是所有可能性实现了,再加_ => println!("match _"),就会报错了

✅ 使用守卫

在 case 中添加 if 语句

match variable { val if 条件 => {...} }
#[test] fn match_script() { let num = 7; match num { n if n < 5 => println!("{} is less than 5", n), n if n % 2 == 0 => println!("{} is even and >=5", n), _ => println!("{} is odd and >=5", num), } }

output

7 is odd and >=5

✅ 引用匹配

#[test] fn match_script() { let s = String::from("hello"); match &s[..] { "hello" => println!("Greeting!"), _ => println!("Something else"), } // s 仍然可用 println!("s is still alive: {}", s); }

output

Greeting! s is still alive: hello

&s[…] 有两层意思

[..]为范围索引取值,语法[a..b],

  • a:起始索引(包含,默认 0);
  • b:结束索引(不包含,默认值为类型的长度);
  • …:省略 start 和 end 时,代表 “从开头到结尾” 的全范围。

&s在这里作用为 String -> &str 类型

match 匹配 String,先转化为字符切片,与 case 数据类型一致,这是常规写法

在这里demo中,match &s[..]等价于match &s

再来看一个示例

#[test] fn match_script() { let x = Some(5); match &x { Some(val) => println!("x is {}", val), None => println!("None"), } println!("x is alive: {}", x.unwrap()); let y = Some(6); match y { Some(val) => println!("y is {}", val), None => println!("None"), } println!("y is alive: {}", y.unwrap()); }

output

x is 5 x is alive: 5 y is 6 y is alive: 6

x y 都正常输出了,通过x.as_ref()借用值使用自然没问题,后续所有权依旧可以使用

但是 5 是可拷贝类型,Some(5)是枚举啊???

这里有个规则:枚举的所有变体的所有关联数据都实现了 Copy 时,枚举才能派生 / 自动实现 Copy

Option 里只有 Some 变体关联了 T,Some(5) 也就意味着该 Option 实现了可 Copy

pub enum Option<T> { None, Some(T), }

换成下面这种写法就会报错,String 不是可拷贝类型

#[test] fn match_script() { let x = Some(String::from("hello")); match x { Some(val) => println!("x is {}", val), None => println!("None"), } println!("x is alive: {}", x.unwrap()); // x 的所有权已经给了 match,如果此处要运行,就需要改成 match &x }

✅ 多条件匹配

#[test] fn match_script() { let day = 6; match day { 1 | 2 | 3 | 4 | 5 => println!("Weekday"), 6 | 7 => println!("Weekend"), _ => println!("Invalid day"), } }

一笔带过

✅ 返回值

#[test] fn match_script() { let status_code = 404; let message = match status_code { 200 => "OK", 404 => "Not Found", 500 => "Internal Server Error", _ => "Unknown", }; println!("Status: {}", message); }

output

Status: Not Found

match 不仅仅起 switch 的作用,还有返回值可以用

如果有变量接收当返回值用时,每个 case 就要有 return 了(上面例子单一字符川也是return)

let message = match status_code { 200 => "OK", 404 => println!("Not Found"), 500 => "Internal Server Error", _ => "Unknown", };

这种编译不过的

✅ Vec/数组匹配

#[test] fn match_script() { let arr = [1, 2, 8]; match arr { [1, 2, 3] => println!("Exact match"), [x, y, ..] => println!("First: {}, Second: {}", x, y), } }

output

First: 1, Second: 2
  1. 匹配向量和数组,长度必须是固定的,比方说你 case 里面写[1, 2, 3, 8]就会报错
  2. [x, y, ..]这种写法会通配匹配,x, y为匹配的向量前两个值,后面的..为通配作用,这个..在一个 case模式 中只允许出现1次,位置随意,[.., y, z][x, .., z]

✅ 写法变种

if let

if 写法式的 match

这种方式通常用于业务中只处理一种模式时,起 if 作用逻辑

#[test] fn match_script() { let optional_target = Some("rustlings"); if let Some(word) = optional_target { println!("match {}", word) } // ...... }

output

match rustlings

等价于下面写法,相当于省去了所有模式的实现

let optional_targets = Some("rustlings"); match optional_targets { Some(word) => println!("match {}", word), None => {} } // ......

while let

while 写法式的 match

常用于重复从某个可变结构中取出值,直到不满足某种模式为止。

非常用于数组向量、元组这类复合数据类型循环遍历

#[test] fn match_script() { let mut optional_integers: Vec<Option<i32>> = vec![Some(3), Some(2), Some(1)]; let mut cursor = 1; while let Some(Some(n)) = optional_integers.pop() { assert_eq!(n, cursor); cursor += 1; } println!("✅ while let works!"); }

output

✅ while let works!
  1. 这里本质是将 while 与 match 的语法结合起来
  2. pop方法是出栈,注意哈,pop的返回值也是一个Option<T>,这里在取值时要解析两层 Option,Some(Some(n))
  3. pop出完栈就没了,组合变量声明表达式(let = xxx)这种写法,形成了一个有限的 while 循环

等价于下面代码

#[test] fn match_script() { let mut optional_integers: Vec<Option<i32>> = vec![Some(3), Some(2), Some(1)]; let mut cursor = 1; loop { match optional_integers.pop() { Some(Some(n)) => { assert_eq!(n, cursor); cursor += 1; } Some(None) => {} None => break, // 向量所有值取完了 } } println!("✅ while let works!"); }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/6 21:51:43

Serverless日志系统构建指南:从基础配置到高级实践

Serverless日志系统构建指南&#xff1a;从基础配置到高级实践 【免费下载链接】serverless-express CodeGenieApp/serverless-express: Serverless Express 是一个库&#xff0c;它允许开发者在无服务器环境下&#xff08;如AWS Lambda、Google Cloud Functions等&#xff09;…

作者头像 李华
网站建设 2026/2/10 10:12:13

GeneFace环境搭建实战指南:从零到一的完整部署流程

GeneFace环境搭建实战指南&#xff1a;从零到一的完整部署流程 【免费下载链接】GeneFace GeneFace: Generalized and High-Fidelity 3D Talking Face Synthesis; ICLR 2023; Official code 项目地址: https://gitcode.com/gh_mirrors/ge/GeneFace 前言&#xff1a;环境…

作者头像 李华
网站建设 2026/2/10 20:17:17

终极指南:快速掌握ChaosBlade混沌工程实战技巧

终极指南&#xff1a;快速掌握ChaosBlade混沌工程实战技巧 【免费下载链接】chaosblade Chaos Blade 是一个分布式混沌工程工具&#xff0c;用于压力测试和故障注入。 * 支持多种云原生应用程序、混沌工程和故障注入、压力测试和故障注入。 * 有什么特点&#xff1a;支持多种云…

作者头像 李华
网站建设 2026/2/7 17:23:45

如何快速掌握Matter协议:智能家居开发者的完整实践指南

如何快速掌握Matter协议&#xff1a;智能家居开发者的完整实践指南 【免费下载链接】connectedhomeip Matter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumer…

作者头像 李华
网站建设 2026/2/11 8:39:40

vLLM多GPU部署终极指南:从零开始构建高性能推理集群

在大模型时代&#xff0c;如何高效部署vLLM推理服务成为每个AI工程师的必修课。想象一下&#xff0c;当你面对8张A100显卡却无法发挥其全部潜力时的挫败感&#xff0c;这正是我们今天要解决的核心问题。 【免费下载链接】verl verl: Volcano Engine Reinforcement Learning for…

作者头像 李华
网站建设 2026/1/30 20:02:51

SeaTunnel Oracle CDC连接器:零基础实战终极指南

SeaTunnel Oracle CDC连接器&#xff1a;零基础实战终极指南 【免费下载链接】seatunnel SeaTunnel是一个开源的数据集成工具&#xff0c;主要用于从各种数据源中提取数据并将其转换成标准格式。它的特点是易用性高、支持多种数据源、支持流式处理等。适用于数据集成和数据清洗…

作者头像 李华