7.枚举和模式匹配

一、enum枚举

1.1 定义枚举类型和对应的数据

//定义枚举
#[derive(Debug)]
enum IpAddrKind{
    IPv4,
    IPv6,
}

struct Ipaddr{
    kind: IpAddrKind,  //设置kind为IpAddrKind的枚举类型
    address: String,
}

fn route(ip_addr: &Ipaddr){
    println!("ip_type = {:#?}", ip_addr.kind);
}

fn main(){
    let home = Ipaddr{
        kind: IpAddrKind::IPv4,   //使用枚举
        address: String::from("127.0.0.1"),
    };

    let loopback = Ipaddr{
        kind: IpAddrKind::IPv6,
        address: String::from("::1"),
    };

    route(&loopback);
    route(&home);
}

上述将枚举与结构体进行绑定,显得过于麻烦,可以按照下面的简写

enum IpAddr{
    IPv4(String),
    IPv6(String),
}

这样简写就可以

  • 不需要额外使用struct
  • 每个数据可以拥有不同的类型以及关联的数据量
enum IpAddr{
    IPv4(String),
    IPv6(String),
    V4(u8,u8,u8,u8),
}

fn main(){
    let home = IpAddr::IPv4(String::from("192.168.0.1"));
    let loopback = IpAddr::IPv6(String::from("::1"));
    let v4 = IpAddr::V4(192, 168, 0, 5);
}

1.2 再来一个比较复杂的

#[derive(Debug)]
enum Message {
    Quit,                       //没有关联任何数据
    Move { x: i32, y: i32 },    //包含一个匿名结构体
    Write(String),              //包含单独一个 String
    ChangeColor(i32, i32, i32), //包含3个i32
}

impl Message {
    fn call(&self) {
        println!("self = {:#?}", self);  //输出self = Write(
                                            //    "hello",
                                             //)
    }
}

fn main() {
    let g = Message::Quit;
    let m = Message::Move { x: 12, y: 24 };
    let w = Message::Write(String::from("Hello"));
    let c = Message::ChangeColor(0, 255, 255);

    w.call();   //w就是call的self值
}

二、Option枚举

2.1 概念

  • Option编码了一个非常普遍的场景,即有值和没值
  • 这就意味着编译器需要检查是否处理了所有应该处理的情况;
  • Rust并没有空值(NULL)的概念;
  • Rust拥有一个可以编码存在或不存在概念的枚举----Option<T>,T是一个泛指类型;
enum Option<T> {
    Some(T),
    None,
}
  • Option<T> 不需要将其显式引入作用域,也不需要Option:: 前缀来直接使用 Some 和 None;
  • 如果使用 None 而不是 Some,需要告诉RustOption<T>是什么类型的;

2.2 举例

1. Some和None

fn main() {
    let some_number = Some(5);
    let some_string = Some("a string");
    let absent_number: Option<i32> = None;
}

2. option<T>和T

  • 这里的T是可以是任何类型;
  • option<T>T是不同的类型;

下面的代码会报错

fn main() {
    let some_number = Some(5);  //编译器自动推断为i32类型
    let som_string = Some("A String");   //编译器自动推断为字符切片(&str)类型
    let absent_number:Option<i32> = None;  //写None时必须显示的声明

    //Option<T>和T是不同的类型, 不可以把Option<T>直接当成T
    //若想使用Option<T>中的T,必须将它转换为T
    let x: i8 = 5;
    let y: Option<i8> = Some(5);

    let sum = x + y;  //^ no implementation for `i8 + Option<i8>`
}

报错信息如下
在这里插入图片描述

  • 在对 Option<T> 进行 T 的运算之前必须将其转换为 T;
  • 能帮助我们捕获到空值最常见的问题之一:假设某值不为空但实际上为空的情况,提高代码的安全性;

三、match模式匹配

3.1 基本用法

  • match匹配允许将一个值与一系列的模式相比较,并根据相匹配的模式执行相应代码;
  • 模式可由字面量、变量、通配符和许多其他内容构成;
enum Coin{
    Penny,
    Nickel,
    Dime,
    Quarter,
}

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

fn main(){
    value_in_cents(Coin::Penny);
}

3.2 绑定值模式

  • 与在枚举成员中提取值相同,匹配分支的另一个有用的功能是可以绑定匹配的模式的部分值;
  • 下面这个例子可以修改一个枚举的成员用来存放数据,打开最终的UsState的值
#[derive(Debug)]
enum UsState{
    Alabama,
    Alaska,
}

enum Coin{
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),  //Quarter关联一个数据
}

fn value_in_cents(coin: Coin) -> u8{
    match coin{
        Coin::Penny => {
            println!("Penny");
            1
        }
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => { //将state绑定到Quarter所存的值上
            println!("State quarter from {:?}!", state);
            25
        }
    }
}

fn main(){
    let c = Coin::Quarter(UsState::Alaska); 
    println!("{}", value_in_cents(c))  //State quarter from Alaska!
}

四、匹配Option<T>

  • 之前使用Option<T>时,是为了从 Some 中取出其内部的 T 值;
  • 这里像处理Coin枚举那样使用match 处理Option<T>中的成员;

下面的函数获取一个Option<i32>,如果其中含有一个值,将其加1;如果其中没有值,函数应该返回 None。

fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1),
    }
}

fn main() {
    let five = Some(5);
    let six = plus_one(five);
    let none = plus_one(None);

    println!("five = {:#?}, six = {:#?} none = {:#?}", five, six, none)
}

打印结果

five = Some(
    5,
), six = Some(
    6,
) none = None

五、穷举

match匹配需要穷举,如下的代码match必须列举完0~255。

fn main() {
    let x:u8 = 9;

    match x {
        0 => {
            println!("0");
        }

        1 => {
            println!("1");
        }
    }
}

代码报错如下,意思就是没有覆盖2到最大值。在这里插入图片描述
这问题加一个_通配符就能解决

fn main() {
    let x:u8 = 9;

    match x {
        0 => {
            println!("0");
        }

        1 => {
            println!("1");
        }

        _ => {
            println!("other");
        }
    }
}

六、if let

  • 只关心一种匹配而忽略其它匹配的情况可以使用if let;
  • 这样也就放弃了穷举的可能;
fn main(){
    let v = Some(3u8);

    match v {
        Some(3) => println!("three"),
        _ => (),
    }

    //和上面的match效果相同
    if let Some(3) = v {
        println!("three");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/702198.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何基于Nginx配置代理服务器实现邮件告警

当代企业信息化系统建设中&#xff0c;将内网与公网进行隔离是一种非常常见的措施&#xff0c;它可以有效保护企业内部数据不被外泄&#xff0c;有助于企业构建一个更加安全的网络环境&#xff0c;保护企业资产和用户隐私。但另一方面&#xff0c;内网与公网隔离也会带来一些问…

【STM32】输入捕获应用-测量脉宽或者频率(方法2)

链接&#xff1a;https://blog.csdn.net/gy3509/article/details/139629893?spm1001.2014.3001.5502&#xff0c;讲述了只使用一个捕获寄存器测量脉宽和频率的方法&#xff0c;其实测量脉宽和频率还有一个更简单的方法就是使用PWM输入模式&#xff0c;PWM输入模式需要占用两个…

推挽式B类功率放大器的基本原理

单晶体管 B 类放大器&#xff08;图 1&#xff09;使用高 Q 值储能电路作为负载来抑制高次谐波分量。通过采用高 Q 谐振电路&#xff0c;输出电压仅包含基波分量&#xff0c;使放大器能够忠实地再现输入信号。尽管集电极电流是半波整流正弦波&#xff0c;但高 Q 值储能电路将谐…

Python基础教程(十):装饰器

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

Non-aligned Supervision for Real Image Dehazing

原文链接&#xff1a;https://www.semanticscholar.org/paper/Non-aligned-supervision-for-Real-Image-Dehazing-Fan-Guo/7595d39e71ae58343e8728fc1af0e18ffe38218b 数据集&#xff1a;https://www.cityscapes-dataset.com/ 真实的图像去雾的非对准监督 摘要 由于天气条件…

淘宝评论数据信息接口

淘宝评论API接口是一种用于获取淘宝用户评论信息的接口&#xff0c;联讯数据可以帮助商家和消费者获取到商品的评价信息&#xff0c;以便更好地了解商品的质量和用户体验。以下是关于淘宝评论API接口的一些内容&#xff1a; 一、接口功能 淘宝评论API接口提供了商品评价信息的…

doc 和 docx 文件的区别

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

第32章-SDN概述

1. SDN的由来 2. SDN的基本概念 1. SDN的由来 计算机产业的发展&#xff1a; 从 1946 年第一代电子管计算机面世到如今&#xff0c;计算机的形态也发生了翻天覆地的变化。从大型机到个人 PC&#xff0c;计算机在不断地推陈出新&#xff0c;且创新发展的势头越加猛烈。究其原因…

信号处理中的相位

相位 用来描述波动或振动状态。 在信号处理和通信领域&#xff0c;相位通常指的是信号相对于某一参考信号的延迟。 在周期性信号中&#xff0c;相位通常以角度&#xff08;弧度或度&#xff09;来表示&#xff0c;表示信号的周期性变化相对于参考信号的位置。 在非周期性信号中…

教你一招,告警恢复时如何拿到恢复时的值?

Prometheus 生态的原生做法&#xff0c;由于阈值是放在 promql 中的&#xff0c;恢复时的消息中难以拿到恢复时的值&#xff0c;夜莺 v7.0.0.beta10 版本开始&#xff0c;提供了一种较为简单的内置方式&#xff0c;解决这个问题。下面我们就来看一下如何实现这个能力。 升级方…

医疗设备维修培训服务的安全性和可靠性

当前&#xff0c;医疗设备维修服务行业市场已经形成了一个庞大的产业链&#xff0c;涵盖了设备检测、故障诊断、维修维护等多个环节。随着医疗设备的日益复杂和高端&#xff0c;对专业维修服务的需求也在不断增加。因此&#xff0c;市场上涌现出了一批专业的医疗设备维修服务提…

Anaconda3 下载安装卸载

1、下载 官网链接&#xff1a;Download Now | Anaconda Step1&#xff1a;进入官网 Anaconda | The Operating System for AI Step2&#xff1a;进入下载页面&#xff0c;选择要Anaconda软件安装包 2、安装 Step1: 点击 Anaconda3-2024.02-1-Windows-x86_64.exe 安装包进行安…

Windows 11中查找和删除旧文件的几种方法,总有一种适合你

序言 如果你的电脑存储空间不足,最好的办法就是找到并删除旧的、不需要的文件。Windows 11提供了多种方法来查找这些占用存储空间的项目,我们将在本指南中向你展示这些方法以及如何使用它们。 使用存储感知 存储感知是Windows 11的内置功能,可帮助自动清理旧文件。你可以…

适合营销的叙事可视化

背景 数据可视化与数据故事化的差异和相似点&#xff0c;以及它们如何协同工作&#xff0c;将你的数据转化为清晰、简洁、可操作的信息&#xff0c;以便您的组织使用。 什么是数据可视化&#xff1f; 数据可视化通过图像传达信息——这是你所收集数据的视觉表示。通过提供原…

(六)React组件通信

理解组件通信 概念&#xff1a;组件通信就是组件之间的数据传递&#xff0c;根据组件嵌套关系不同&#xff0c;有不同的通信方式。 A - B 父子通信B - C 兄弟通信A - E 跨层通信 1. 父传子 – 基础实现 实现步骤&#xff1a; 父组件传递数据 - 在子组件标签上绑定属性子组…

eNSP学习——配置高级的访问控制列表

目录 主要命令 原理概述 实验目的 实验内容 实验拓扑 实验编址 实验步骤 1、基本配置 2、搭建OSPF网络 3、配置Telnet 4、配置高级ACL控制访问 需要eNSP各种配置命令的点击链接自取&#xff1a;华为&#xff45;NSP各种设备配置命令大全PDF版_ensp配置命令大全资源-…

使用Stream实现Web应用,使用YOLOv8模型对图像进行目标检测为例。

Streamlit是一个开源的Python框架&#xff0c;专门设计用于快速构建和共享数据应用程序。它使数据科学家和机器学习工程师能够通过编写简单的Python脚本&#xff0c;轻松创建美观、功能强大的Web应用程序&#xff0c;而无需具备前端开发的经验。 其他框架或web应用可以看下面两…

【全开源】Java无人共享棋牌室茶室台球室系统JAVA版本支持微信小程序+微信公众号

无人共享棋牌室系统——棋牌娱乐新体验 &#x1f3b2;引言 随着科技的不断发展&#xff0c;传统棋牌室正逐渐迈向智能化、无人化。今天&#xff0c;我要为大家介绍的就是这款引领潮流的“无人共享棋牌室系统”。它不仅为棋牌爱好者提供了全新的娱乐体验&#xff0c;更在便捷性…

SpringCloudNetflix组件整合

SpringCloudNetflix组件整合 Eureka注册中心 Eureka是什么 Eureka是netflix的一个子模块&#xff0c;也是核心模块之一&#xff0c;Eureka是一个基于REST的服务&#xff0c;用于定位服务&#xff0c;以实现云端中间层服务发现和故障转移。服务注册与发现对于微服务架构来说是…

复制网页文字和图片到Word中-Word插件-大珩助手

问题整理&#xff1a; 为什么从浏览器的网页上复制文字和图片后&#xff0c;在Word中粘贴时图片无法显示&#xff1f;有没有插件可以将网页中的文字和图片复制到Office Word 中&#xff1f; Word大珩助手是一款功能丰富的Office Word插件&#xff0c;旨在提高用户在处理文档时…