• rust -枚举和模式匹配学习(二)


    通过对《Rust 程序设计语言》,《通过例子学 Rust 中文版》以及令狐一冲老师对相关知识点的学习总结而成。

    1 Option定义形式

    空值尝试表达的概念仍然是有意义的:空值是一个因为某种原因目前无效或缺失的值。
    问题不在于概念而在于具体的实现。为此,Rust 并没有空值,不过它确实拥有一个可以编码存在或不存在概念的枚举。这个枚举是 Option,而且它定义于标准库中,其形式为:

    enum Option<T> {
    	Some(T),
    	None,
    }
    
    • 1
    • 2
    • 3
    • 4

    Option 枚举是如此有用以至于它甚至被包含在了 prelude 之中,你不需要将其显式引入作用域。另外,它的成员也是如此,可以不需要 Option:: 前缀来直接使用 Some 和 None。即便如此 Option 也仍是常规的枚举,Some(T) 和 None 仍是 Option 的成员。
    注: 语法是一个泛型类型参数。

    2 Option的使用方式

    let some_number = Some(5);
    let some_string = Some("a string");
    
    let absent_number: Option<i32> = None;
    
    • 1
    • 2
    • 3
    • 4

    Option 和 T(这里 T 可以是任何类型)是不同的类型,编译器不允许像一个肯定有效的值那样使用 Option。

    3 匹配 Option

    fn plus_one(x: Option<i32>) -> Option<i32> {
        match x {
            None => None,
            Some(i) => Some(i + 1),
        }
    }
    
    fn main() {
        let five = Some(5);
    
        let none = plus_one(None);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4 匹配 Some(T)

    fn plus_one(x: Option<i32>) -> Option<i32> {
        match x {
            None => None,
            Some(i) => Some(i + 1),
        }
    }
    
    fn main() {
        let five = Some(5);
    
        let none = plus_one(None);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    让我们更仔细地检查 plus_one 的第一行操作。当调用 plus_one(five) 时,plus_one 函数体中的 x 将会是值 Some(5)。接着将其与每个分支比较。

    None => None,
    
    • 1

    值 Some(5) 并不匹配模式 None,所以继续进行下一个分支。

    Some(i) => Some(i + 1),
    
    • 1

    Some(5) 与 Some(i) 匹配吗?当然匹配!它们是相同的成员。i 绑定了 Some 中包含的值,所以 i 的值是 5。接着匹配分支的代码被执行,所以我们将 i 的值加一并返回一个含有值 6 的新 Some。

    接着考虑下示例中 plus_one 的第二个调用,这里 x 是 None。我们进入 match 并与第一个分支相比较。

    None => None,
    
    • 1

    匹配上了!这里没有值来加一,所以程序结束并返回 => 右侧的值 None,因为第一个分支就匹配到了,其他的分支将不再比较。

    下面是一个对Some(T)匹配做进一步处理的例子。

    fn plus_one(x: Option<i32>) -> Option<i32> {
        match x {
            None => None,
            Some(i) => Some(i + 1),
        }
    }
    
    fn main() {
        let five = Some(5);
    
    	let res = plus_one(five);
    	match res {	//此处的match要把所有的情况都处理完
    		Some(i) => println!("res = {}", i),
    		None => println!("None"),
    	};
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    5 if let 简单控制流

    match的时候要把它所有的情况都做出处理,但是存在我们只需要处理其中仅关心的一两种模式的情形。
    if let 语法让我们以一种不那么冗长的方式结合 if 和 let,来处理只匹配一个模式的值而忽略其他模式的情况。
    如下所举的示例:虽然我们只关注了Some(T)的match分支,但是其他不关心的分支还是需要通过_ 通配符去做对应的处理。

    let some_u8_value = Some(0u8);
    match some_u8_value {
        Some(3) => println!("three"),
        _ => (),
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    下面我们来看if let的使用方式:

    let some_u8_value = Some(0u8);
    if let Some(3) = some_u8_value {
        println!("three");
    }
    
    if let Some(value) = plus_one(five) {
    	println!("value is {}", value);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    排课系统.admin.coursetask
    word如何实现不同章节显示不同页眉
    没什么。。。。
    CCF CSP认证 历年题目自练Day18
    linux操作Swap
    LeetCode-1408-数组中的字符串匹配
    计算机毕业设计Java在线问诊系统的设计与实现(源码+系统+mysql数据库+Lw文档)
    什么是国内生产总值(GDP)
    Java判断字符串、对象、list是否为空总结
    .NET 采用 SkiaSharp 生成二维码和图形验证码及图片进行指定区域截取方法实现
  • 原文地址:https://blog.csdn.net/u014100559/article/details/127822151