Rust模式匹配

在rust模式匹配中,单纯的下划线和下划线开头的变量有什么区别呢?

let s = Some(String::from("Hello!"));

if let Some(_s) = s {
    println!("found a string");
}

println!("{:?}", s);

这段代码会报错,因为s的所有权转移到了_s上面,但是如果不用_s而是使用_的话,就不会报错了。

模式匹配的每一个分支的返回值类型必须相同

每一个分支的最后一句话必须是一个语句,代表要返回的东西。
所以match本身也是一个表达式,可以用来赋值。

enum Direction {
    East,
    West,
    North,
    South,
}

fn main() {
    let dire = Direction::South;
    match dire {
        Direction::East => println!("East"),
        Direction::North | Direction::South => {
            println!("South or North");
        },
        _ => println!("West"),
    };
}

在和这个例子中,所有分支的返回值类型都是相同的。
但是下面例子呢?

enum Direction {
    East,
    West,
    North,
    South,
}

fn main() {
    let dire = Direction::South;
    match dire {
        Direction::East => println!("East"),
        Direction::North | Direction::South => {
            println!("South or North");
            12
        },
        Direction::West => println!("West"),
    };
}

运行结果是:

Compiling world_hello v0.1.0 (/home/jie/rust/world_hello)
error[E0308]: `match` arms have incompatible types
  --> src/main.rs:14:13
   |
10 | /     match dire {
11 | |         Direction::East => println!("East"),
   | |                            ---------------- this is found to be of type `()`
12 | |         Direction::North | Direction::South => {
13 | |             println!("South or North");
14 | |             12
   | |             ^^ expected `()`, found integer
15 | |         },
16 | |         Direction::West => println!("West"),
17 | |     };
   | |_____- `match` arms have incompatible types

For more information about this error, try `rustc --explain E0308`.
error: could not compile `world_hello` (bin "world_hello") due to 1 previous error

所以分支的返回值类型必须相同。

if let 匹配

fn main() {
    let v = Some(3u8);
    match v {
        Some(3) => println!("three"),
        _ => (),
    }

    if let Some(3) = v{
        println!("hello");
    }

    if v == Some(3){
        println!("world");
    }
}

这个if let是只用于匹配match中单一的某一种类型的时候用的。
那为什么不直接用一个if来判断不就行了吗?
观察如下情况:

fn main() {
   
    let five = Some(5);
    
    let six = plus_one(five);
    println!("{:?}", six);
}

fn plus_one(x: Option<i32>) -> Option<i32> {
    if x == Some(i) {  // 这行代码报错
        
    }

    if let Some(i) = x{
        return Some(i + 1);
    }

    return None;
}

上面这种情况汇总,if是不能解构出i的值的,只能是一个确定的值。
本质原因是一种叫模式绑定的东西。
模式匹配的另外一个重要功能是从模式中取出绑定的值,例如:
Option的定义是

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

这个Option绑定了一个T。当我们需要获取到这个T的时候,就可以用到模式绑定的语法特性。
但是if是不能获取到的。

fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1),
    }
}

在这个代码中,Option中的T被绑定到了i上面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值