Rust匹配守卫

目录

匹配命名变量的覆盖问题

匹配守卫

@绑定

@绑定转换为匹配守卫

总结 


匹配命名变量的覆盖问题

fn main() {
    let x = Some(5);
    let y = 10;

    match x {
        Some(50) => println!("Got 50"),

        Some(y) => println!("Matched, y = {:?}", y),
        //这里的y不会读取外部的y变量, 而是some(y)匹配上的值,本例中就是5,而不是10   
        //这在一定程度上造成了歧义,也让默认分支失去了意义

        _ => println!("Default case, x = {:?}", x),
    }

    //当然随着match表达式的结束,内部的y变量被释放,所以并没有对外部的y进行修改(只是内部覆盖)
    println!("at the end: x = {:?}, y = {:?}", x, y);
}

 如果你不想引入变量覆盖,那么需要使用匹配守卫(match guard)的方式


匹配守卫


匹配守卫match guard)是一个位于 match 分支模式之后的额外 if 条件,它能为分支模式提供更进一步的匹配条件。 

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),
        //这里让 n与y 真正发生了关系---相等,同时并没有覆盖外部的变量
        //默认分支同时存在意义

        _ => println!("Default case, x = {:?}", x),
    }

    println!("at the end: x = {:?}, y = {}", x, y);
}

@绑定

@(读作 at)运算符允许为一个字段绑定另外一个变量

fn main() {
    enum Message {
        Hello { id: i32 },
    }
    
    let msg = Message::Hello { id: 5 };
    
    match msg {
        Message::Hello { id: id_variable @ 3..=7 } => {
            println!("Found an id in range: {}", id_variable)
            //注意这里是不能读取id的,因为id绑定到另外一个变量id_variable中,且为id_variable设定3到7的限制范围
        },

        Message::Hello { id: 10..=12 } => {
            println!("Found an id in another range")
            //注意这里也是不能读取id的
        },

        Message::Hello { id } => {
            println!("Found some other id: {}", id)
            //这里却是可以读取id的
        },
    }
}

 第二个分支只在模式中指定了一个范围,id 字段的值可以是 10、11 或 12,不过这个模式的代码并不知情也不能使用 id 字段中的值,因为没有将 id 值保存进一个变量。

@绑定转换为匹配守卫

fn main() {

    enum Message {
        Hello { id: i32 },
    }

    let msg = Message::Hello { id: 11 };

    match msg {
        Message::Hello { id  } if id >3 && id <7 => {
            println!("Found an id in range: {}", id)
        },
        Message::Hello { id } if id >10 && id<12 => {
            println!("Found an id in another range , {}" , id)
        },
        Message::Hello { id } => {
            println!("Found some other id: {}", id)
        },
    }
}

但其实我们会发现这是这种转换关系的非常麻烦的,也就是不建议这样使用,因为只需要一个分支并在其内部进行if判断更加直截了当

match msg {
        Message::Hello { id  } => {
            if id >3 && id <7{
                println!("Found an id in range: {}", id)
            }
            else if id >10 && id<12{
                println!("Found an id in another range , {}" , id)
            }
            else{
                println!("Found some other id: {}", id)
            }
            
        }
    }

总结 

        综上可以知道,匹配守卫可以解决变量覆盖问题,匹配守卫还可以与@绑定相互转换,有时候匹配守卫写法更加简单;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值