用到模式的位置

match

match表达式必须是穷尽的(exhaustive),要求考虑所有状况,但一般用_运算符匹配所有剩余情况:

  1. match VALUE {
  2. PATTERN => EXPRESSION,
  3. PATTERN => EXPRESSION,
  4. PATTERN => EXPRESSION,
  5. }

if let

用于只考虑一种匹配的情况,可以指定else分支来匹配所有剩余情况:

  1. if let PATTERN = VALUE {
  2. EXPRESSION;
  3. }else if let PATTERN2 = VALUE2 {
  4. EXPRESSION;
  5. }else{
  6. EXPRESSION;
  7. }

可以搭配更多的:

  • else if let匹配新的模式,不同的if let的模式不会相互干扰
  • 或者使用else if,普通的分支语句
  • 或者使用else,匹配其他情况

whild let

匹配模式时,持续循环,与if let相似:

  1. while let PATTERN = VALUE {
  2. EXPRESSION;
  3. }

for循环

for x in y中的x也是模式匹配,有解构功能:

  1. for PATTERN in VALUE{
  2. EXPRESSION
  3. }

let语句

let语句本身就是模式匹配,只是会匹配任意的值
let PATTERN = VALUE;

函数参数

  1. fn f(PATTERN: TYPE){};
  2. f(VALUE);

可反驳性

模式有两种形式:

  • irrefutable(不可反驳的),表示模式一定会匹配成功,会接收传过来的任何值
    • let
    • 函数参数
    • for循环
  • refutable(可反驳性的),表示模式可能会匹配失败,不会执行此模式相应的表达式
    • match表达式
    • if let表达式
    • whild let表达式

模式语法

match的匹配方式

匹配到字面值

match表达式中直接使用字面值,提供最精确的模式匹配

  1. let v = 1
  2. match v {
  3. 1 => println!("111"),
  4. _ => println!("___")
  5. }

匹配到变量

使用match表达式匹配到枚举的变体v匹配了a中定义的任何值,并作为局部变量传给后面的表达式

  1. let a = Some(5)
  2. match a{
  3. Some(v) => println!("{}",v),
  4. _ => println!("___")
  5. }

匹配到多个情况

使用**|**符号分隔多个模式

  1. let a = Some(5)
  2. match a{
  3. Some(1) | Some(5) => println!("{}",v),
  4. _ => println!("___")
  5. }

匹配到范围

使用**..**的形式指定一个范围,如果值在这个范围内,则可以匹配成功

  1. let a = Some(5);
  2. match a {
  3. Some(1..=5) => println!("1-5"),
  4. _ => println!("___"),
  5. }

匹配守卫

在模式后面附加上**if**语句,可以提供额外条件,需要注意:if后面的条件只是普通的表达式,并不是一个模式

  1. let a = Some(5);
  2. match a {
  3. Some(v) if v > 3 => println!("4-5"),
  4. _ => println!("___"),
  5. }

@ 绑定

使用@绑定,可以先将值匹配到变量,然后拿值去匹配模式

下面第一个模式中:先把值绑定到**id_variable**后再拿值去匹配模式
第二个模式中:直接拿值去匹配模式,没有绑定到变量
第三个模式中:实际上用的是结构体解构的简写语法**id:id**,将值绑定到了变量id

  1. enum Message {
  2. Hello { id: i32 },
  3. }
  4. let msg = Message::Hello { id: 5 };
  5. match msg {
  6. Message::Hello { id: id_variable @ 3..=7 } => {
  7. println!("Found an id in range: {}", id_variable)
  8. },
  9. Message::Hello { id: 10..=12 } => {
  10. println!("Found an id in another range")
  11. },
  12. Message::Hello { id } => {
  13. println!("Found some other id: {}", id)
  14. },
  15. }

解构赋值

需要注意的是,除了数据部分,其他的部分要在形式上完全对应

结构体

需要使用这个结构体的格式来解构结构体,变量同名的话可简写

  1. struct Point {
  2. x: f64,
  3. y: f64,
  4. }
  5. let p = Point { x: 2.2, y: 3.3 };
  6. let Point { x:a, y:b } = p;
  7. println!("a:{},b:{}", a, b);

用途:
可以用于从结构体获取部分变量的形式
可用于match的模式匹配,只指定部分变量的值

枚举

用于match表达式,解构枚举需要在形式上完全对应,数据部分可以使用变量形式

元组

使用let语句解构并赋值到变量
let ((feet, inches), Point {x, y}) = ((3, 10), Point { x: 3, y: -10 });

忽略部分值

使用_占位符忽略值

可以用在:

  • match的最后一个分支
  • Some(_)中,用于匹配任意值
  • 函数签名的参数中,表示忽略这个参数
  • 在元组解构中作为占位符 ```rust let numbers = (2, 4, 8, 16, 32);

match numbers { (first, , third, , fifth) => { println!(“Some numbers: {}, {}, {}”, first, third, fifth) }, }

  1. <a name="rSotW"></a>
  2. ### 使用`..`忽略剩余值
  3. 用作:
  4. - 结构体的解构赋值中,可以忽略剩余的不用的变量
  5. - 扩展为所需要的值的数量
  6. ```rust
  7. fn main() {
  8. let numbers = (2, 4, 8, 16, 32);
  9. match numbers {
  10. (first, .., last) => {
  11. println!("Some numbers: {}, {}", first, last);
  12. },
  13. }
  14. }