Rust编程语言入门之模式匹配
Posted 小乔的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rust编程语言入门之模式匹配相关的知识,希望对你有一定的参考价值。
模式匹配
模式
- 模式是Rust中的一种特殊语法,用于匹配复杂和简单类型的结构
- 将模式与匹配表达式和其他构造结合使用,可以更好地控制程序的控制流
- 模式由以下元素(的一些组合)组成:
- 字面值
- 解构的数组、enum、struct 和 tuple
- 变量
- 通配符
- 占位符
- 想要使用模式,需要将其与某个值进行比较:
- 如果模式匹配,就可以在代码中使用这个值的相应部分
一、用到模式(匹配)的地方
match 的 Arm
match VALUE
PATTERN => EXPRESSION,
PATTERN => EXPRESSION,
PATTERN => EXPRESSION,
- match 表达式的要求:
- 详尽(包含所有的可能性)
- 一个特殊的模式:_(下划线):
- 它会匹配任何东西
- 不会绑定到变量
- 通常用于 match 的最后一个 arm;或用于忽略某些值。
条件 if let 表达式
- if let 表达式主要是作为一种简短的方式来等价的代替只有一个匹配项的 match
- if let 可选的可以拥有 else,包括:
- else if
- else if let
- 但,if let 不会检查穷尽性
fn main()
let favorite_color: Option<&str> = None;
let is_tuesday = false;
let age: Result<u8, _> = "34".parse();
if let Some(color) = favorite_color
println!("Using your favorite color, , as the background", color);
else if if_tuesday
println!("Tuesday is green day!");
else if let Ok(age) = age
if age > 30
println!("Using purple as the background color");
else
println!("Using orange as the background color");
else
println!("Using blue as the background color");
While let 条件循环
- 只要模式继续满足匹配的条件,那它允许 while 循环一直运行
fn main()
let mut stack = Vec::new();
stack.push(1);
stack.push(2);
stack.push(3);
while let Some(top) = stack.pop()
println!("", top);
for 循环
- for 循环是Rust 中最常见的循环
- for 循环中,模式就是紧随 for 关键字后的值
fn main()
let v = vec![\'a\', \'b\', \'c\'];
for (index, value) in v.iter().enumerate()
println!(" is at index ", value , index);
Let 语句
- let 语句也是模式
- let PATTERN = EXPRESSION
fn main()
let a = 5;
let (x, y, z) = (1, 2, 3);
let (q, w) = (4, 5, 6); // 报错 类型不匹配 3 2
函数参数
- 函数参数也可以是模式
fn foo(x: i32)
// code goes here
fn print_coordinates(&(x, y): &(i32, i32))
println!("Current location: (, )", x, y);
fn main()
let point = (3, 5);
print_coordinates(&point);
二、可辩驳性:模式是否会无法匹配
模式的两种形式
- 模式有两种形式:可辨驳的、无可辩驳的
- 能匹配任何可能传递的值的模式:无可辩驳的
- 例如:
let x = 5;
- 例如:
- 对某些可能得值,无法进行匹配的模式:可辩驳的
- 例如:
if let Some(x) = a_value
- 例如:
- 函数参数、let 语句、for 循环只接受无可辩驳的模式
- if let 和 while let 接受可辨驳和无可辩驳的模式
fn main()
let a: Option<i32> = Some(5);
let Some(x) = a: // 报错 None
if let Some(x) = a
if let x = 5 // 警告
三、模式语法
匹配字面值
- 模式可直接匹配字面值
fn main()
let x = 1;
match x
1 => println!("one"),
2 => println!("two"),
3 => println!("three"),
_ => println!("anything"),
匹配命名变量
- 命名的变量是可匹配任何值的无可辩驳模式
fn main()
let x = Some(5);
let y = 10;
match x
Some(50) => println!("Got 50"),
Some(y) => println!("Matched, y = :?", y),
_ => println!("Default case, x = :?", x),
println!("at the end: x = :?, y = :?", x, y);
多重模式
- 在match 表达式中,使用 | 语法(就是或的意思),可以匹配多种模式
fn main()
let x = 1;
match x
1 | 2 => println!("one or two"),
3 => println!("three"),
_ => println!("anything"),
使用 ..= 来匹配某个范围的值
fn main()
let x = 5;
match x
1..=5 => println!("one through five"),
_ => println!("something else"),
let x = \'c\';
match x
\'a\' ..=\'j\' => println!("early ASCII letter"),
\'k\' ..=\'z\' => println!("late ASCII letter"),
_ => println!("something else"),
解构以分解值
- 可以使用模式来解构 struct、enum、tuple,从而引用这些类型值的不同部分
struct Point
x: i32,
y: i32,
fn main()
let p = Point x: 0, y: 7 ;
let Point x: a, y: b = p;
assert_eq!(0, a);
assert_eq!(7, b);
let Point x, y = p;
assert_eq!(0, x);
assert_eq!(7, y);
match p
Point x, y: 0 => println!("On the x axis at ", x),
Point x: 0, y => println!("On the y axis at ", y),
Point x, y => println!("On neither axis: (, )", x, y),
解构 enum
enum Message
Quit,
Move x: i32, y: i32,
Write(String),
ChangeColor(i32, i32, i32),
fn main()
let msg = Message::ChangeColor(0, 160, 255);
match msg
Message::Quit =>
println!("The Quit variant has no data to destructure.")
Message::Move x, y =>
println!("Move in the x direction and in the y direction ", x, y);
Message::Write(text) => println!("Text message: ", text),
Message::ChangeColor(r, g, b) =>
println!("Change the color to red , green , and blue ", r, g, b);
解构嵌套的 struct 和 enum
enum Color
Rgb(i32, i32, i32),
Hsv(i32, i32, i32),
enum Message
Quit,
Move x: i32, y: i32,
Write(String),
ChangeColor(Color),
fn main()
let msg = Message::ChangeColor(Color::Hsv(0, 160, 255));
match msg
Message::ChangeClolr(Color::Rgb(r, g, b)) =>
println!("Change the color to red , green , and blur ", r, g, b)
Message::ChangeColor(Color::Hsv(h, s, v)) =>
println!("Change the color to hue , saturation , and value ", h, s, v)
_ => (),
解构 struct 和 tuple
struct Point
x: i32,
y: i32,
fn main()
let ((feet, inches), Point x, y) = ((3, 10), Point x: 3, y: -10);
在模式中忽略值
- 有几种方式可以在模式中忽略整个值或部分值:
- _
- _ 配合其它模式
- 使用以 _ 开头的名称
- .. (忽略值的剩余部分)
使用 _ 来忽略整个值
fn foo(_: i32, y: i32)
println!("This code only uses the y parameter: ", y);
fn main()
foo(3, 4);
使用嵌套的 _ 来忽略值的一部分
fn main()
let mut setting_value = Some(5);
let new_setting_value = Some(10);
match (setting_value, new_setting_value)
(Some(_), Some(_)) =>
println!("Can\'t overwrite an existing customized value");
_ =>
setting_value = new_setting_value;
println!("setting is :?", setting_value);
let numbers = (2, 4, 6, 8, 16, 32);
match numbers
(first, _, third, _, fifth) =>
println!("Some numbers: , , ", first, third, fifth)
通过使用 _ 开头命名来忽略未使用的变量
fn main()
let _x = 5;
let y = 10; // 创建未使用 警告
let s = Some(String::from("Hello"));
if let Some(_s) = s // if let Some(_) = s
println!("found a string");
println!(":?", s); // 报错
使用 .. 来忽略值的剩余部分
struct Point
x: i32,
y: i32,
z: i32,
fn main()
let origin = Point x: 0, y: 0, z: 0;
match origin
Point x, .. => println!("x is ", x),
let numbers = (2, 4, 8, 16, 32);
match numbers
(first, .., last) =>
println!("Some numbers: , ", first, last);
match numbers
(.., second, ..) => // 报错
println!("Some numbers: ", second)
,
使用 match 守卫来提供额外的条件
- match 守卫就是 match arm 模式后额外的 if 条件,想要匹配该条件也必须满足
- match 守卫适用于比单独的模式更复杂的场景
例子一:
fn main()
let num = Some(4);
match num
Some(x) if x < 5 => println!("less than five: ", x),
Some(x) => println!("", x),
None => (),
例子二:
fn main()
let x = Some(5);
let y = 10;
match x
Some(50) => println!("Got 50"),
Some(n) if n == y => println!("Matched, n = :?", n),
_ => println!("Default case, x = :?", x),
println!("at the end: x = :?, y = :?", x, y);
例子三:
fn main()
let x = 4;
let y = false;
match x
4 | 5 | 6 if y => println!("yes"),
_ => println!("no"),
@绑定
- @ 符号让我们可以创建一个变量,该变量可以在测试某个值是否与模式匹配的同时保存该值
enum Message
Hello id: i32,
fn main()
let msg = Message::Hello id: 5;
match msg
Message::Hello
id: id_variable @ 3..=7,
=>
println!("Found an id in range: ", id_variable)
Message::Hello id: 10..=12 =>
println!("Found an id in another range")
Message::Hello id =>
println!("Found some other id: ", id)
本文来自博客园,作者:QIAOPENGJUN,转载请注明原文链接:https://www.cnblogs.com/QiaoPengjun/p/17343139.html
Rust编程语言入门之项目实例:- 命令行程序
项目实例:- 命令行程序
一、实例:接收命令行参数
本章内容
- 12.1 接收命令行参数
- 12.2 读取文件
- 12.3 重构:改进模块和错误处理
- 12.4 使用 TDD(测试驱动开发)开发库功能
- 12.5 使用环境变量
- 12.6 将错误消息写入标准错误而不是标准输出
创建项目
~/rust
➜ cargo new minigrep
Created binary (application) `minigrep` package
~/rust
➜ cd minigrep
minigrep on master [?] via 以上是关于Rust编程语言入门之模式匹配的主要内容,如果未能解决你的问题,请参考以下文章