Rust控制流运算符match的用法详解

 更新时间:2024年01月28日 10:40:46   作者:qq5551230  
match 是Rust中一个极为强大的控制流运算符,用于模式匹配和控制流的选择,它允许将一个值与一系列的模式相比较,根据匹配的模式执行相应代码,本文给大家详细介绍了Rust控制流运算符match的用法,需要的朋友可以参考下

概述

match 是Rust中一个极为强大的控制流运算符,用于模式匹配和控制流的选择。它允许将一个值与一系列的模式相比较,根据匹配的模式执行相应代码。模式可由字面量、变量、通配符和许多其他内容构成。

模式由以下元素(的一些组合)组成:

  • 字面量
  • 解构的数组
  • 枚举类型
  • 结构体
  • 处理条件表达式
  • 通配符
  • 占位符

我们可以把match表达式想象成某种硬币分类器:硬币滑入有着不同大小孔洞的轨道,每个硬币都会掉入符合它大小的空洞。同样地,值也会通过match的每一个模式,并且在遇到第一个“符合”的模式时,值会进入相关的代码块并在执行中被使用。

基础语法

match value {
    pattern1 => {
        //code1
    }
    pattern2 => {
        //code2
    }
    _ => {
        //没有任何匹配
    }
}

基础语法中,value是要匹配的变量,pattern是匹配模式, => 后面是要执行的代码。末尾使用通配符“ - ”(下划线)表示其他情况。如果value匹配了某个模式,就执行相应代码块,如果value没有匹配任何模式,就会执行默认的代码块,即( _ => {...},)。

让我们编写一个函数来获取一个未知的硬币,并以一种类似验钞机的方式,确定它时何种硬币并返回它的美分值。

//一个枚举和一个以枚举成员作为模式的match表达式
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}
 
fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}

如果分支代码较短的话通常不使用大括号,如果想要在分支中运行多行代码,可以使用大括号。

fn value_in_cents(coin:Coin) -> u8 {
    match coin {
        Coin::Penny => {
            println!("Lucy penny!");
            1
        }
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter =>25,
    }
}

绑定值的模式

匹配分支的另一个有用的功能是可以绑定匹配的模式的部分值。也就是可以从枚举成员中提取值的方式。

举个例子,让我们修改枚举中的一个成员来存放数据。1999年到2008年间,美国在25美分的硬币的一侧为50个州的每一个都印刷了不同的设计。其他的硬币都没有这种区分州的设计,只有这些25美分的硬币有特殊的价值。可以将这些信息加入我们的enum,通过改变Quarter成员来包含一个State值。

//Quarter成员也存放一个UsState值的Coin枚举
#[derive(Debug)]
enum UsState {
    Alabama,
    Alaska,
    //--snip--
}
 
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),
}

假设我们的一个朋友正在尝试收集所有50个州25美分硬币。根据硬币类型分类零钱的同时,也可以报告出每个25美分硬币所对应的州名称,如果他没有的话,他可以将其加入收藏。

fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime =>10,
        Coin::Quarter(state) => {
            println!("State quarter from {:?}!", state);
            25
        }
    }
}

调用value_in_cents(Coin::Quarter(UsState::Alaska),coin将是Coin::Quarter(UsState::Alaska)。这时state绑定的值是UsState::Alaska。然后在pintln!表达式中使用这个绑定就可以获取Coin枚举的Quarter成员中内部的州的值。

匹配Option<T>

我们想要编写一个函数,它获取一个Option<i32>,如果其中含有一个值,将其加一。如果其中没有值,函数应该返回None值,二不尝试执行任何操作。

// 一个Option<i32>上使用match表达式的函数
fn plus_one (x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i+1),
    }
}
 
let five = Some(5);
let six =plus_one(five);
let none = plus_one(None);

匹配Some(T)

匹配是穷尽的

Rust知道我们没有覆盖所有可能的情况甚至指导哪些模式被忘记了!Rust中的匹配时穷尽的:必须穷举到最后的可能性来使代码有效。特别是在Option<T>的例子中,Rust防止我们忘记明确的处理None的情况,这让我们免于假设拥有一个实际上为空的值,从而错误不可能发生。

通配符和 _ 占位符

假设我们正在玩一个游戏,如果你掷出骰子的值为3,角色不会移动,而是会得到一顶新奇的帽子。如果掷出骰子的值为7,你的角色将失去新奇的帽子。对于其他的数值,你的角色会在棋盘上移动相应的格子。

let dice_roll = 9;
match dice_roll {
    3 => add_fancy_hat(),
    7 => remove_fancy_hat(),
    other => move_player(other),
}
 
fn add_fancy_hat() {}
fn remove_fancy_hat() {}
fn move_player(num_spaces: u8) {}

这是一个实现上述逻辑的match,匹配模式是字面值3和7,最后一个分支则涵盖了所有其他可能的值,模式是我们命名为other的一个变量。other分支的代码通过将其传递给move_player函数来使用这个变量。

最后一个模式没有列出u8所有可能的值,代码依旧能够编译。这种通配模式满足了match必须被穷尽的要求,必须将通配分支放在最后,因为模式是按顺序匹配的。

当我们不想使用通配模式获取的值时,可以使用 _ 模式。这个模式可以匹配任意值而不绑定到该值。

改变游戏规则:现在,当你掷出觉得值不是3或7的时候,你必须再次掷出。这种情况下我们不需要使用这个值。我们修改代码使用"_"代替变量other:

let dice_roll = 9;
match dice_roll {
    3 => add_fancy_hat(),
    7 => remove_fancy_hat(),
    _ => reroll(),
}
 
fn add_fancy_hat() {}
fn remove_fancy_hat() {}
fn reroll() {}

最后一个分支中明确忽略了其他的值,也满足了穷举性要求。

改变游戏规则:如果掷出3或7以外的值,你的回合将无事发生。使用单元值(空元组)作为_分支的代码:

let dice_roll = 9;
match dice_roll {
    3 => add_fancy_hat(),
    7 => remove_fancy_hat(),
    _ => (),
}
 
fn add_fancy_hat() {}
fn remove_fancy_hat() {}

到此这篇关于Rust控制流运算符match的用法详解的文章就介绍到这了,更多相关Rust控制流运算符match内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Rust中的Drop特性之解读自动化资源清理的魔法

    Rust中的Drop特性之解读自动化资源清理的魔法

    Rust通过Drop特性实现了自动清理机制,确保资源在对象超出作用域时自动释放,避免了手动管理资源时可能出现的内存泄漏或双重释放问题,智能指针如Box、Rc和RefCell都依赖于Drop来管理资源,提供了灵活且安全的资源管理方案
    2025-02-02
  • Rust语言数据类型的具体使用

    Rust语言数据类型的具体使用

    在Rust中,每个值都有一个明确的数据类型,本文主要介绍了Rust语言数据类型的具体使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-04-04
  • Rust 通过异步实现并发的方法示例

    Rust 通过异步实现并发的方法示例

    本文主要介绍了Rust 通过异步实现并发的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-06-06
  • rust交叉编译问题及报错解析

    rust交叉编译问题及报错解析

    这篇文章主要为大家介绍了rust交叉编译问题及报错解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • 详解Rust中三种循环(loop,while,for)的使用

    详解Rust中三种循环(loop,while,for)的使用

    我们常常需要重复执行同一段代码,针对这种场景,Rust 提供了多种循环(loop)工具。一个循环会执行循环体中的代码直到结尾,并紧接着回到开头继续执行。而 Rust 提供了 3 种循环:loop、while 和 for,下面逐一讲解
    2022-09-09
  • Rust中的函数指针详解

    Rust中的函数指针详解

    Rust是一种现代的系统编程语言,它支持函数指针。函数指针是指向函数的指针,可以将函数作为参数传递给其他函数或存储在变量中。Rust中的函数指针可以用于实现回调函数、动态分发和多态等功能。本文将介绍Rust中的函数指针的基本用法和高级用法。
    2023-05-05
  • Rust 多线程编程的实现

    Rust 多线程编程的实现

    在rust中,多线程编程不算困难,但是也需要留心和别的编程语言中不同的地方,本文主要介绍了Rust 多线程编程的实现,感兴趣的可以了解一下
    2023-12-12
  • Rust之模式与模式匹配的实现

    Rust之模式与模式匹配的实现

    Rust中的模式匹配功能强大且灵活,它极大地提高了代码的表达力和可读性,本文主要介绍了Rust之模式与模式匹配,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • 深入解析Rust中的智能指针

    深入解析Rust中的智能指针

    本文介绍了Rust中的智能指针,Box、Rc、Arc、RefCell、Mutex、RwLock对应的功能、场景与常用方法,并提供了组合使用方式,以及Cow、Pin的使用方式,感兴趣的朋友跟随小编一起看看吧
    2025-10-10
  • Rust获取命令行参数及IO操作方法

    Rust获取命令行参数及IO操作方法

    Rust作为一门系统编程语言,提供了强大且安全的I/O操作支持,本文给大家介绍Rust获取命令行参数以及IO操作,感兴趣的朋友一起看看吧
    2025-06-06

最新评论