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异步流处理方法详细讲解

    RUST异步流处理方法详细讲解

    这篇文章主要介绍了RUST异步流处理方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • rust中间件actix_web在项目中的使用实战

    rust中间件actix_web在项目中的使用实战

    这篇文章主要介绍了rust中间件在项目中的使用实战,包括自定义中间件,日志中间件,Default headers,用户会话,错误处理的用法实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • Rust Postgres实例代码

    Rust Postgres实例代码

    Rust Postgres是一个纯Rust实现的PostgreSQL客户端库,本文主要介绍了Rust Postgres实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-05-05
  • 详解在Rust语言中如何声明可变的static类型变量

    详解在Rust语言中如何声明可变的static类型变量

    在Rust中,可以使用lazy_static宏来声明可变的静态变量,lazy_static是一个用于声明延迟求值静态变量的宏,本文将通过一个简单的例子,演示如何使用 lazy_static 宏来声明一个可变的静态变量,需要的朋友可以参考下
    2023-08-08
  • Rust编写自动化测试实例权威指南

    Rust编写自动化测试实例权威指南

    这篇文章主要为大家介绍了Rust编写自动化测试实例权威指南详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Windows系统下安装Rust环境超详细教程

    Windows系统下安装Rust环境超详细教程

    这篇文章主要介绍了如何在Windows系统上安装mingw64和Rust,mingw64是一个轻便的C语言编译环境,可以替代Rust默认使用的Visual Studio,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2025-02-02
  • 深入理解 Rust 中的模式匹配语法(最新推荐)

    深入理解 Rust 中的模式匹配语法(最新推荐)

    Rust中的模式匹配提供了多种方式来处理不同的数据类型和场景,本文给大家介绍Rust 中的模式匹配语法,感兴趣的朋友一起看看吧
    2025-03-03
  • 如何基于Rust实现文本搜索minigrep

    如何基于Rust实现文本搜索minigrep

    这篇文章主要介绍了基于Rust实现的文本搜索minigrep,本次演示介绍针对原作者代码程序的查询逻辑做了一点点小的优化,原程序逻辑的查询是放在了程序运行的时候,逻辑修改后启动的时候可以添加参数,也可以启动后添加,需要的朋友可以参考下
    2024-08-08
  • Rust重载运算符之复数四则运算的实现

    Rust重载运算符之复数四则运算的实现

    这篇文章主要为大家详细介绍了Rust如何实现复数以及复数的四则运算,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-08-08
  • rust声明式宏的实现

    rust声明式宏的实现

    声明式宏使得你能够写出类似 match 表达式的东西,来操作你所提供的 Rust代码,它使用你提供的代码来生成用于替换宏调用的代码,感兴趣的可以了解一下
    2023-12-12

最新评论