当前位置:   article > 正文

Rust学习教程22 - 全模式列表_rust 嵌套结构

rust 嵌套结构

本文节选自<<Rust语言圣经>>一书
欢迎大家加入Rust编程学院,一起学习交流:
QQ群:1009730433

全模式列表

在本书中我们已领略过许多不同类型模式的例子. 本节的目标就是把这些模式语法都罗列出来,方便大家检索查阅。

匹配字面值

let x = 1;

match x {
   
    1 => println!("one"),
    2 => println!("two"),
    3 => println!("three"),
    _ => println!("anything"),
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这段代码会打印 one 因为 x 的值是 1。如果希望代码获得特定的具体值,则该语法很有用。

匹配命名变量

match一章中,我们有讲过变量覆盖的问题,这个在匹配命名变量时会遇到:

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

让我们看看当 match 语句运行的时候发生了什么。第一个匹配分支的模式并不匹配 x 中定义的值,所以代码继续执行。

第二个匹配分支中的模式引入了一个新变量 y,它会匹配任何 Some 中的值。因为我们在 match 表达式的新作用域中,这是一个新变量,而不是开头声明为值 10 的那个 y。这个新的 y 绑定会匹配任何 Some 中的值,在这里是 x 中的值。因此这个 y 绑定了 xSome 内部的值。这个值是 5,所以这个分支的表达式将会执行并打印出 Matched, y = 5

如果 x 的值是 None 而不是 Some(5),头两个分支的模式不会匹配,所以会匹配模式_。这个分支的模式中没有引入变量 x,所以此时表达式中的 x 会是外部没有被覆盖的 x

一旦 match 表达式执行完毕,其作用域也就结束了,同理内部 y 的作用域也结束了。最后的 println! 会打印 at the end: x = Some(5), y = 10

如果你不想引入变量覆盖,那么需要使用匹配守卫(match guard)的方式,稍后在匹配守卫提供的额外条件中会讲解。

单分支多模式

match 表达式中,可以使用 | 语法匹配多个模式,它代表 的意思。例如,如下代码将 x 的值与匹配分支相比较,第一个分支有 选项,意味着如果 x 的值匹配此分支的任何一个模式,它就会运行:

let x = 1;

match x {
   
    1 | 2 => println!("one or two"),
    3 => println!("three"),
    _ => println!("anything"),
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面的代码会打印 one or two

通过序列..= 匹配值的范围

数值类型中我们有讲到一个序列语法,该语言不仅可以用循环中,还能用于匹配模式。

..= 语法允许你匹配一个闭区间序列内的值。在如下代码中,当模式匹配任何在此序列内的值时,该分支会执行:

let x = 5;

match x {
   
    1..=5 => println!("one through five"),
    _ => println!("something else"),
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如果 x 是 1、2、3、4 或 5,第一个分支就会匹配。这相比使用 | 运算符表达相同的意思更为方便;相比 1..=5,使用 | 则不得不指定 1 | 2 | 3 | 4 | 5。相反指定序列就简短的多,特别是在希望匹配比如从 1 到 1000 的数字的时候!

序列只允许用于数字或字符类型,因为编译器会在编译时检查序列不为空。字符和数字值是 Rust 仅有的可以判断范围是否为空的类型。

如下是一个使用字符类型序列的例子:

let x = 'c';

match x {
   
    'a'..='j' => println!("early ASCII letter"),
    'k'..='z' => println!("late ASCII letter"),
    _ => println!("something else"),
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Rust 知道 c 位于第一个模式的序列内,并会打印出 early ASCII letter

解构并分解值

也可以使用模式来解构结构体、枚举、元组和引用。

解构结构体

下面代码展示了如何用let解构一个带有两个字段 xy 的结构体 Point

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/556715
推荐阅读
相关标签
  

闽ICP备14008679号