7.枚举和模式匹配

news2024/12/23 9:40:06

一、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");
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

arxiv提交报错解决指南

- 编译时无错误 - 所有文件和图片文件都在同一目录下 - 生成.bbl文件 overleaf将参考文献格式bib转bbl&#xff08;bibitem&#xff09;_overleaf bbl文件-CSDN博客 - .tex文件、.bib文件、.bbl文件 的文件名要一致&#xff0c;修改.bib文件名记得在.tex文件中修改bibliograp…

成都产业园运营,多样活动助力生态建设

树莓集团在成都产业园的运营中&#xff0c;通过举办多样化的活动&#xff0c;积极助力产业园的生态建设。 企业服务活动 企业间交流会议与项目对接会&#xff1a;树莓集团定期组织企业间的交流会议和项目对接会&#xff0c;旨在促进不同企业之间的信息沟通和合作机会&#xff…

自动控制原理【期末复习】

1.结构图化简 &#xff08;左图中左边的成为比较点&#xff0c;右面的成为引出点&#xff09; &#xff08;右图中注意反馈通路的符号是正是负&#xff09; H1的引出点后移&#xff0c;找H1的反馈通路&#xff0c;观察在原反馈通路上加上了G4,所以乘上1/G4 2.传递函数 求误差传…

5.5 业务流程和业务逻辑设计

一、引言 1.1 项目背景 经过上述的论述&#xff0c;我们讨论一下业务流程和业务逻辑设计&#xff0c;通过合理的业务流程设计和业务逻辑设计&#xff0c;可以提高用户的购物体验&#xff0c;降低用户的操作成本&#xff0c;并确保用户的购物行为符合平台的规则和要求。同时&a…

移民月贺礼!世贸通EB-5移民项目首批投资人获批了

特大喜讯 第八届移民月正在如火如荼地开展中 世贸通迎来了一个令人振奋的好消息 为移民月送来了一份大礼 增添了一抹格外耀眼的光彩 由世贸通担任大中华区独家代理的 「佛罗里达湖畔犹太社区」EB-5乡村项目 迎来首批投资人I-526E获批 世贸通恭喜获得I-526E批准的投资家庭…

分享视频的二维码怎么制作?扫码看视频的生成技巧

视频现在很多人会通过二维码的方式来分享&#xff0c;与使用软件、网盘、u盘等方式相比&#xff0c;将视频转换成二维码的方式可以更加简单的实现内容的传播与分享&#xff0c;并且有效提升用户体验。视频制作二维码可以提升内容的安全性&#xff0c;无需用户去下载存储视频&am…

【code-server】Code-Server 安装部署

Code-Server 安装部署 1.环境准备 可以参考 https://coder.com/docs/code-server/install code-server的安装流程进行安装&#xff0c;主机环境是 Centos7 建议使用 docker 方式进行安装&#xff0c;可能会出现如下报错&#xff0c;需要升级 GNC 的版本&#xff0c;由于影响交…

怎么在电脑上修改图片大小?图片在线处理大小的方法

图片是目前很常用的一种信息或者内容的展现方式&#xff0c;所以在很多的场景中都会应用&#xff0c;但是在使用图片的时候&#xff0c;经常会受到图片大小限制的要求&#xff0c;比如需要将图片尺寸修改到指定尺寸才可以上传&#xff0c;那么在线改图片大小如何实现呢&#xf…

国内核心期刊基本情况

对于广大师生来说&#xff0c;发表核心期刊论文是当前阶段绕不开的任务&#xff0c;有的高校晋升副高需要发表核心论文5篇以上&#xff0c;有的学校硕博研究生毕业条件必须是一作发核心。很多人对核心的理解仅停留在“北核、南核”&#xff0c;其他的一概不知。但是我国的核心期…

在Java中,子类继承了父类,子类和父类都定义了一个静态方法,一个午无参构造方法,一个play方法,如果调用子类的play方法的话执行顺序是什么

静态方法的调用: 静态方法是与类本身相关的,而不是与具体的对象实例相关。当调用子类的play方法时,首先会查找子类自身是否有定义静态方法,如果有,则执行子类的静态方法。如果子类没有定义静态方法,则会向上查找父类,执行父类的静态方法。 构造方法的调用: 当创建子类对象时,…

Autohotkey使用记录

文章目录 1. 安装1.1 autohotkey1.2 vscode需要安装的插件 3. 函数使用3.1 按键3.2 MouseMove 4. Bug分析4.1 A_TimeSincePriorHotkey 1. 安装 1.1 autohotkey 下载安装即可 1.2 vscode需要安装的插件 3. 函数使用 3.1 按键 各个按键的代词使用关键字搜索&#xff1a;Hotk…

AnythingLLM 的 Docker 使用

AnythingLLM是使用大语言模型LLM的一站式简便框架。官网的介绍如下&#xff1a; AnythingLLM is the easiest to use, all-in-one AI application that can do RAG, AI Agents, and much more with no code or infrastructure headaches. 1. 使用官方docker 最方便的方法是使…

AiP74LVC1T45GB236.TR SOT23-6缓冲器/驱动器双电源接口电平转换

AIP74LVC1T45GB236.TR 是一款电平转换芯片&#xff0c;它的应用领域非常广泛&#xff0c;主要包括&#xff1a; 1. 嵌入式系统&#xff1a;在嵌入式系统中&#xff0c;由于不同的外设可能工作在不同的电源电压下&#xff0c;该电平转换器可用于确保微控制器和其他逻辑电路之间的…

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

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

垫付商贩任务补单平台补单系统网站源码提供

垫付商贩任务补单平台补单系统网站源码提供

MBR20100FCT-ASEMI肖特基二极管MBR20100FCT

编辑&#xff1a;ll MBR20100FCT-ASEMI肖特基二极管MBR20100FCT 型号&#xff1a;MBR20100FCT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;20A 最大循环峰值反向电压&#xff08;VRRM&#xff09;&#xff1a…

点亮数据之光:Matplotlib让你的数据图表闪耀星空!

在数据的海洋中&#xff0c;Matplotlib是那座通往洞见彼岸的彩虹桥。阿佑带你一探究竟&#xff0c;如何用Matplotlib解锁数据的神秘力量。从基础图表的绘制到高级技巧的掌握&#xff0c;我们一步步揭开数据可视化的神秘面纱。无论你是数据科学家还是图表爱好者&#xff0c;阿佑…

同城信息房产出租小程序源码系统 完全开源可二次开发 带完整的安装代码包以及搭建教程

系统概述 在数字化转型的浪潮中&#xff0c;房产租赁市场也迎来了新的发展机遇。随着移动互联网的普及&#xff0c;越来越多的用户倾向于通过手机应用或小程序来寻找合适的租房信息。为了满足这一需求&#xff0c;小编给大家分享一款“同城信息房产出租小程序源码系统”&#…

pepy - Python 包下载量统计工具站

文章目录 一、关于 pepy站点使用显示下载量 二、代码贡献依赖环境配置启动环境 三、架构和模式四、常问问题 一、关于 pepy 官网&#xff1a;https://www.pepy.techgithub : https://github.com/psincraian/pepy 前端&#xff1a;https://github.com/psincraian/pepy-front 站…

如何给让公众号合集通过调整顺序增加文章阅读量?

公众号合集备点开的次数和顺序的关系是怎样的&#xff1f; 1、排序与点击率的关系 公众号在一次推送中的链接顺序确实会影响用户对各链接的点击率。通常&#xff0c;第一条和最后一条链接的点击率会大于中间的链接。这是基于用户的阅读习惯和注意力分布的一个普遍现象。 2、…