Rust 数据类型 之 类C枚举 c-like enum

目录

枚举类型 enum

定义和声明

例1:Color 枚举

例2:Direction 枚举

例3:Weekday 枚举

类C枚举 C-like

打印输出

强制转成整数

例1:Weekday 枚举

例2:HttpStatus 枚举

例3:Color 枚举

模式匹配

match 表达式

枚举方法


枚举类型 enum

枚举类型是一种用于表示一组有限数量相互关联的离散型数据,这些值可以是不同的整数、字符串或其他类型的对象。枚举体内的元素称作“成员”,rust语言中,枚举里面的成员,都可以被看作是结构体,当然枚举还能嵌套另一个枚举。

定义和声明

在Rust中,枚举类型可以通过关键字enum来定义:

enum MyEnum {
    Variant1,
    Variant2,
    Variant3,
    //...
    VariantN,
}

enum是enumerate/enumeration的缩略词,MyEnum为自定义的枚举名

Variant即变量的意思,有的译作“变体”,我觉得还是沿用C/C++语言中的称呼“成员”比较恰当。

Variant数量N一定有限的,太多的变量堆砌没有意义;而且N>=2,无成员或单个成员也无意义。

通过使用枚举类型,可以为不同的情况定义一组有限的取值。这在需要表示多个可能状态或选项的情况下非常有用。以下是几个常见的枚举类型经典实例:

例1:Color 枚举

Color 枚举表示颜色的不同可能取值,比如红色、绿色和蓝色。

enum Color {
    Red,
    Green,
    Blue,
}

例2:Direction 枚举

Direction 枚举表示方向的不同可能取值,比如上、下、左和右。

enum Direction {
    Up,
    Down,
    Left,
    Right,
}

例3:Weekday 枚举

Weekday 枚举表示一周中的不同天,比如一周7天的枚举。

enum Weekday {
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,    
}

类C枚举 C-like

与C/C++语言中的枚举成员只允许是usigned int型常量,也称枚举常量。Rust中具有C风格的枚举,那么必须满足枚举里面的成员都是单元结构体

打印输出

使用#[derive(Debug)]简化输出,格式:println!("{:?}", MyEnum::VariantN); 

#[derive(Debug)]
enum Number {
    Zero,
    One,
    Two,
    Three,
}

fn main() {
    println!("zero is {:?}", Number::Zero);
    println!("one is {:?}", Number::One);
    println!("Two is {:?}", Number::Two);
    println!("Three is {:?}", Number::Three);
}

输出:

zero is Zero
one is One
Two is Two
Three is Three

强制转成整数

不使用#[derive(Debug)],强制转化为整数后输出

enum Number {
    Zero,
    One,
    Two,
    Three,
}

fn main() {
    println!("zero is {}", Number::Zero as i32);
    println!("one is {}", Number::One as i32);
    println!("Two is {}", Number::Two as i32);
    println!("Three is {}", Number::Three as i32);
}

输出:

zero is 0
one is 1
Two is 2
Three is 3

类C枚举也可以通过赋值运算,变成一组离散的整数:

#![allow(dead_code)]

#[derive(Debug)]
enum Number {
    Zero,
    One,
    Two,
    Five = 5,
    Six,
}

fn main() {
    println!("zero is {}", Number::Zero as i32);
    println!("one is {}", Number::One as i32);
    println!("Five is {}", Number::Five as i32);
    println!("Six is {}", Number::Six as i32);
}

输出:

0
1
5

注:在整个程序中枚举成员Two没被调用过,可以用#![allow(dead_code)]来滤去警告。没有此行,上述程序在编译执行能输出结果,但同时警告:warning: variant `Two` is never constructed。

例1:Weekday 枚举

Weekday 枚举通过赋值,使得星期一到星期日对应整数1~7;而非默认的星期日到星期六对应整数0~6。

#![allow(dead_code)]

enum Weekday {
    Sunday = 7,
    Monday = 1,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
}

fn main() {
    println!("Sunday is {}", Weekday::Sunday as i32);
    println!("Tuesday is {}", Weekday::Tuesday as i32);
    println!("Saturday is {}", Weekday::Saturday as i32);
}

输出:

Sunday is 7
Tuesday is 2
Saturday is 6 

例2:HttpStatus 枚举

HttpStatus 枚举表示不同的 HTTP 状态码,比如200表示成功,404表示找不到页面,500表示服务器内部错误等,共有近百个成员,列举部分如下:

#![allow(dead_code)]

 enum HttpStatus {
    Continue = 100, //"CONTINUE" 继续
    SwitchingProtocols, //"SWITCHING_PROTOCOLS" 切换协议
    Processing, //"PROCESSING" 执行
    Checkpoint, //"CHECKPOINT" 检查点
    OK = 200, //"OK" OK
    CREATED, //"Created" 创建
    ACCEPTED, //"Accepted" 接受
    NonAuthoritativeInformation, //"NON_AUTHORITATIVE_INFORMATION" 非权威信息
    NoContent, //"NO_CONTENT" 没有内容
    ResetContent, //"RESET_CONTENT" 重置内容
    PartialContent, //"PARTIAL_CONTENT" 部分内容
    MultiStatus, //"MULTI_STATUS" 多个状态
    AlreadyReported, //"ALREADY_REPORTED" 已发
    IMUsed = 226, //"IM_USED" 已过时
    MultipleChoices = 300, //"MULTIPLE_CHOICES" 多选择
    MovedPermanently, //"MOVED_PERMANENTLY" 永久移动
    FOUND, //"Found" 找到
    MovedTemporarily, //"MOVED_TEMPORARILY"
    SeeOther, //"SEE_OTHER" 参见其它
    NotModified, //"NOT_MODIFIED" 未修改
    UseProxy, //"USE_PROXY"),
    TemporaryRedirect, //"TEMPORARY_REDIRECT" 暂时重定向
    PermanentRedirect, //"PERMANENT_REDIRECT" 永久重定向
    //......
    BadRequest = 400, //"BAD_REQUEST" 错误请求
    Unauthorized, //"UNAUTHORIZED" 未经授权
    PaymentRequired, //"PAYMENT_REQUIRED" 付费请求
    Forbidden, //"FORBIDDEN" 禁止
    NotFound, //"NOT_FOUND" 未找到
    MethodNotAllowed, //"METHOD_NOT_ALLOWED" 方法不容许
    NotAcceptable, //"NOT_ACCEPTABLE" 方法不接受
    //......
    InternalServerError = 500, // "INTERNAL_SERVER_ERROR" 服务器遇到了意料不到的情况,不能完成客户的请求
    NotImplemented, //"NOT_IMPLEMENTED"  服务器不支持实现请求所需要的功能
    BadGateway, //"BAD_GATEWAY" 从上游服务器接收到无效的响应
    ServiceUnavailable, //"SERVICE_UNAVAILABLE" 服务不可用
    GatewayTimeout, //"GATEWAY_TIMEOUT") 网关不能及时地从远程服务器获得应答
    //......
}

fn main() {
    println!("OK is {}", HttpStatus::OK as i32);
    println!("Bad Request is {}", HttpStatus::BadRequest as i32);
}

输出:

OK is 200
Bad Request is 400

例3:Color 枚举

用{:06x}格式输出6位16进制数表示的颜色

enum Color {
    Red = 0xff0000,
    Green = 0x00ff00,
    Blue = 0x0000ff,
}

fn main() {
    println!("roses are #{:06x}", Color::Red as i32);
    println!("leaves are #{:06x}", Color::Green as i32);
    println!("violets are #{:06x}", Color::Blue as i32);
    println!("red is {}", Color::Red as i32);
    println!("green is {}", Color::Green as i32);
    println!("blue is {}", Color::Blue as i32);
}

输出:

roses are #ff0000
leaves are #00ff00
violets are #0000ff
red is 16711680
green is 65280
blue is 255 

模式匹配

枚举类型在 Rust 中经常与模式匹配(pattern matching)结合使用,以根据枚举类型的值执行不同的操作。

match 表达式

match 表达式可以用于对枚举变体进行模式匹配,并根据所匹配的变体执行相应的代码块。它的语法如下:

match value {
    pattern1 => {
        // 如果 value 匹配了 pattern1
    },
    pattern2 => {
        // 如果 value 匹配了 pattern2
    },
    // 其他模式...
}

如定义一个名为 Color 的枚举类型,其中包含了三个成员:Red、Green 和 Blue。每个成员都是一个合法的标识符,用于表示不同的颜色。

enum Color {
    Red,
    Green,
    Blue,
}

对上述的 Color 枚举类型,可以使用模式匹配来执行相应的操作:

fn print_color(color: Color) {
    match color {
        Color::Red => println!("The color is Red"),
        Color::Green => println!("The color is Green"),
        Color::Blue => println!("The color is Blue"),
    }
}

上述示例中,函数 print_color 接收一个 Color 类型的参数,并使用 match 进行模式匹配。根据传入的颜色值,会执行相应的操作。

枚举方法

还可以自定义方法,为每个成员定义相应的值。

#![allow(dead_code)]

enum Color {
    Red,
    Green,
    Blue,
    Yellow,
    Magenta,
    Cyan,
}

impl Color {
    fn to_rgb(&self) -> (u8, u8, u8) {
        match self {
            Color::Red => (255, 0, 0),
            Color::Green => (0, 255, 0),
            Color::Blue => (0, 0, 255),
            Color::Yellow => (255, 255, 0),
            Color::Magenta => (255, 0, 255),
            Color::Cyan => (0, 255, 255),
        }
    }
}
  
fn main() {
    let red = Color::Red;
    let red_rgb = red.to_rgb();
    println!("RGB value of red: {:?}", red_rgb);
    
    let yellow = Color::Yellow;
    let yellow_rgb = yellow.to_rgb();
    println!("RGB value of yellow: {:?}", yellow_rgb);
}

在上述示例中,我们为 Color 枚举类型实现了一个 to_rgb 方法,用于将颜色转换为 RGB 值。

总结起来,Rust 的枚举类型提供了强大的模式匹配功能,使得枚举类型非常灵活和可靠,适用于各种场景和数据处理需求。本文只初步学习类C风格的枚举类型,其它分类且听下回分解。

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

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

相关文章

使用 Docker 快速上手官方版 LLaMA2 开源大模型

本篇文章,我们聊聊如何使用 Docker 容器快速上手 Meta AI 出品的 LLaMA2 开源大模型。 写在前面 昨天特别忙,早晨申请完 LLaMA2 模型下载权限后,直到晚上才顾上折腾了一个 Docker 容器运行方案,都没来得及写文章来聊聊这个容器怎…

wxchart 小程序 线条图不显示y轴的网格线 (分割线)

如下图:项目需求不显示包括x轴的6条灰色分割线。 分析: 看了一下源码已经写死了是5条分割线,加一条x轴刻度线。没给公开配置方法。 解决方案: 既然没有配置项目,可以转变思路,把这些线条配置成白色&…

Spring整合Mybatis原理

首先介绍一下Mybatis的工作原理 先简略的放两张图,后面的知识结合这两张图比较好理解 Mybatis的基本工作原理 在 Mybatis 中,我们可以使用⼀个接口去定义要执行sql,简化代码如下: 定义⼀个接口,Select 表示要执行查询…

【UniApp开发小程序】”我的“界面实现+“信息修改“界面实现+登出账号实现+图片上传组件【基于若依管理系统开发】

文章目录 界面实现界面效果我的修改信息 “我的”界面实现api页面退出账号让自我介绍只显示一行,结尾多余的字使用...代替跳转到信息修改页面 信息修改界面实现api页面动态给对象设置属性名和值修改密码图片上传组件 部分后端代码Controller 界面实现 界面效果 我…

Windows11的VTK安装:VS201x+Qt5/Qt6 +VTK7.1/VTK9.2.6

需要提前安装好VS2017和VS2019和Qt VS开发控件以及Qt VS-addin。 注意Qt6.2.4只能跟VTK9.2.6联合编译(目前VTK9和Qt6的相互支持版本)。 首先下载VTK,需要下载源码和data: Download | VTKhttps://vtk.org/download/ 然后这两个文…

1 请使用js、css、html技术实现以下页面,表格内容根据查询条件动态变化。

1.1 创建css文件,用于编辑style 注意: 1.背景颜色用ppt的取色器来获取: 先点击ppt的形状轮廓,然后点击取色器,吸颜色,然后再点击形状轮廓的其他轮廓颜色,即可获取到对应颜色。 2.表格间的灰色线…

什么是搜索引擎?2023 年搜索引擎如何运作?

目录 什么是搜索引擎?搜索引擎的原理什么是搜索引擎爬取?什么是搜索引擎索引?什么是搜索引擎检索?什么是搜索引擎排序? 搜索引擎的目的是什么?搜索引擎如何赚钱?搜索引擎如何建立索引?网页抓取文本处理建…

【数字图像处理与应用】模板匹配

【数字图像处理与应用】模板匹配 题目模板匹配原理Matlab代码实现算法介绍显示图像的匹配结果 (最匹配的一个)MATLAB实现运行结果图像的相关值结果:在原图像上绘制检测到的目标位置:显示检测到的目标坐标: 显示图像的匹配结果 (最匹配的三个&…

聊聊spring-cloud的负载均衡

聊聊spring-cloud的负载均衡 1. 选择合适的负载均衡算法2. 合理设置超时时间3. 缓存服务实例列表4. 使用断路器5. 使用缓存Spring Cloud负载均衡组件对比RibbonLoadBalancerWebClient对比 总结 在微服务架构中,负载均衡是非常重要的一个环节,可以有效地提…

python与深度学习(六):CNN和手写数字识别二

目录 1. 说明2. 手写数字识别的CNN模型测试2.1 导入相关库2.2 加载数据和模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章训练的模型进行测试…

极速跳板机登陆服务器

目录 一:简单登陆跳板器二:一键申请相关的服务器权限三:简化登陆 一:简单登陆跳板器 登陆公司提供的网址, 下载自己的专属RSA密钥。在密钥文件处, 执行登陆指令: ssh -p 36000 -i id_rsa 用户跳…

LAXCUS分布式操作系统:人工智能最后一公里

随着人工智能技术的飞速发展,越来越多的应用场景开始涌现。然而,在实际应用中,人工智能技术仍然面临着许多挑战,其中最大的挑战之一就是如何实现人工智能的“最后一公里”。这一问题主要体现在以下几个方面: 计算资源…

程序员进阶之路:程序环境和预处理

目录 前言 程序的翻译环境和执行环境 翻译环境 运行环境 预处理(预编译) 预定义符号 #define #define 定义标识符 #define 定义宏 #define 替换规则 #和## #的作用 ##的作用 带副作用的宏参数 宏和函数对比 命名约定 #undef 命令行定义 条件…

Task :app:javaPreCompileDebug FAILED

一,报错内容 在打包react native项目的时候,报错如下信息,我的项目的react-native版本比较低,是0.62… > Task :app:javaPreCompileDebug FAILED Execution failed for task :app:javaPreCompileDebug. > Could not resolve all files for configuration :app:debugCom…

Windows下YUICompress实现js、css混淆压缩

首先,我们针对Linux下的部分命令进行Windows系统的对应实现 ls————cmd /c dir/b rm————cmd /c del mv————cmd /c move pwd————cmd /c chdir 注:cmd /c是执行完命令后关闭命令行窗口、cmd /k是执行完命令后不关闭命令行窗口、cmd /c sta…

关于计算机的各种编码

ASCII编码 ASCII (American Standard Code for Information Interchange):美国信息交换标准代码是基于的一套电脑编码系统,主要用于显示现代英语和其他语言。它是最通用的标准,并等同于国际标准 ISO/IEC 646。ASCII第一次以规范标准的类型发表…

如何在 SwiftUI 中使用 Touch ID 和 Face ID?

1. 需要通过指纹,面容认证后才能打开 App 2. 添加配置 需要向 Info.plist 文件中添加一个配置,向用户说明为什么要访问 添加 Privacy - Face ID Usage Description 并为其赋予值 $(PRODUCT_NAME) need Touch Id or Face ID permission for app lock 3. …

sql中group by 的使用

1、概述 Group By 从字面意义上理解就是根据By指定的规则对数据进行分组,所谓的分组就是将一个数据集划分为若干个小区域,然后针对若干个小区域进行数据处理 2、原始表 3、简单的Group By 示例1 select 类别,数量 as 数量之和 from A gro…

​MySQL高阶语句(三)

目录 1、内连接 2、左连接 3、右连接: 二、存储过程⭐⭐⭐ 4. 调用存储过程 5.查看存储过程 5.1 查看存储过程 5.2查看指定存储过程信息 三. 存储过程的参数 3.1存储过程的参数 3.2修改存储过程 四.删除存储过程 MySQL 的连接查询,通常都是将来…

(css)原生html实现遮罩层弹窗

(css)原生html实现遮罩层弹窗 效果&#xff1a; html <div class"overlay"><div class"content"><!-- 需要遮罩的内容 --> <el-table :data"tableData" size"mini" class"table-class" border stripe…