ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Rust中的模式匹配

2021-11-28 14:32:34  阅读:264  来源: 互联网

标签:匹配 Point Some Rust let 模式匹配 println match


一、let模式匹配

在其它一些语言中,let x = 5 之类的语句,仅仅只是赋值语句。但是在rust中,可以换个角度理解,认为5这个值匹配到了x变量。如果觉得有些牵强,可以再来一个示例:

    let (a,b)=(1,3);
    println!("{},{}",a,b);

上面的示例,表示(1,3)这个元组,匹配(a,b)这一组变量,即a=1, b=3,类似的,struct也可以这样匹配:

struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p = Point { x: 10, y: 20 };
    //模式匹配
    let Point { x, y } = p;
    //x=10,y=20
    println!("x:{},y:{}", x, y);
}

  

二、match匹配

2.1 匹配简单类型

    let x = 1;
    match x {
        1 => println!("x=1"),
        2 => println!("x=2"),
        //"_"相当于java中switch的default
        _ => println!("default"),
    }

    let y = 2;
    match y {
        //匹配1或2
        1 | 2 => println!("y=1 or 2"),
        _ => println!("default"),
    }

    let z = 1;
    match z {
        //匹配1到5
        1..=5 => println!("z between 1 and 5"),
        _ => println!("default"),
    }

    let c = 'z';
    match c {
        //匹配a到z
        'a'..='z' => println!("{} in [a-z]", c),
        _ => println!("other"),
    }

2.2 匹配枚举

以最常用的Option enum为例:

    let x = Some(2);
    let x_result = match x {
        //精确匹配Some(5),x=Some(2),会匹配失败
        Some(5) => 5,
        _ => -1,
    };
    println!("{}",x_result);

    let x = Some(2);
    let x_result = match x {
        //只要x有值,就能匹配成功
        Some(n) => n,
        _ => -1,
    };
    println!("{}",x_result);

    let x = Some(3);
    let x_result = match x {
        //匹配时,还能指定条件,3>1,下面这行会匹配成功
        Some(n) if n>1 => n,
        _ => -1,
    };
    println!("{}",x_result);

输出:

-1
2
3

另外,有些情况下,match还可以用if let语法糖简化代码:

    if let Some(v) = Some(5) {
        println!("{}", v);
    };

    //上面的代码,等效于下面这几行:
    let w = Some(5);
    match w {
        Some(n) => {
            println!("{}", n)
        }
        _ => {}
    }

有时候,只需要匹配enum类型,不关注值,可以用_来忽略值

    let x = Some(4);
    let y = Some(5);
    match(x,y){
        (Some(_),Some(_)) => println!("both are Some Type"),
        _ => println!("others")
    }

关于“_”,还有一些小技巧,如果只声明1个变量,不使用,rust编译器会警告:

上图的提示,已经给出建议,可以加_,即改成let _x=10,就不会报警了。

另外_在模式匹配中,还可以避免所有权转移:

    let s = Some(String::from("hello"));
    //由于_不关注值,所以s的所有权不会move到_
    if let Some(_) = s{
        println!("found a string");
    }
    //这里能正常输出
    println!("s:{:?}",s);

但如果,把Some(_),换成其它方式,比如

不仅仅是系统自带的enum,开发人员自定义的enum也一样可以进行匹配:

    enum Order {
        New { order_id: i32 },
    }

    let o1 = Order::New { order_id: 1 };

    match o1 {
        Order::New { order_id: x } if x >= 0 && x <= 10 => {
            println!("order_id:{} between 0 and 10", x)
        }
        _ => {}
    }

    //与上面的写法等效(注意多了1个@符号,表示把匹配到的值,赋值到@修饰的变量n里)
    match o1 {
        Order::New {
            order_id: n @ 1..=10,
        } => println!("order_id:{} between 0 and 10", n),
        _ => {}
    }

2.3 匹配元组

    let t = (1, 2,3);
    match t {
        //仅匹配第1项,其它元素忽略
        (1, ..) => println!("first item is 1"),
        _ => println!("default"),
    }

    let t = (2, 3);
    match t {
        //匹配第1项,第2项放到变量n里
        (1, n) => println!("{},{}", 1, n),
        _ => println!("default"),
    }

    let t = (1, 2, 3, 4, 5, 6);
    match t {
        //匹配第1项与最后1项
        (1, .., 6) => println!("first:1,last:6"),
        _ => println!("others"),
    }

2.4 匹配struct

    struct Point {
        x: i32,
        y: i32,
    }

    let p = Point { x: 10, y: 20 };
    match p {
        Point { x: 10, y: 20 } => println!("完全匹配!"),
        Point { x: 5, y } => println!("要求x匹配5,y无所谓"),
        Point { x, y } => println!("p中的x,y匹配到{},{}", x, y),
        _ => println!("others"),
    }

标签:匹配,Point,Some,Rust,let,模式匹配,println,match
来源: https://www.cnblogs.com/yjmyzz/p/15614552.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有