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

news2024/10/6 19:00:24

目录

枚举类型 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风格的枚举类型,其它分类且听下回分解。

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

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

相关文章

opencv 图像距离变换 distanceTransform

图像距离变换:计算图像中每一个非零点距离离自己最近的零点的距离,然后通过二值化0与非0绘制图像。 #include "iostream" #include "opencv2/opencv.hpp" using namespace std; using namespace cv;int main() {Mat img, dst, dst…

【STL】模拟实现简易 list

目录 1. 读源码 2. 框架搭建 3. list 的迭代器 4. list 的拷贝构造与赋值重载 拷贝构造 赋值重载 5. list 的常见重要接口实现 operator--() insert 接口 erase 接口 push_back 接口 push_front 接口 pop_back 接口 pop_front 接口 size 接口 clear 接口 别…

数字验证码识别新思路及对opencv支持向量机机器学习总结

验证码识别框架 新问题 最近遇到了数字验证码识别的新问题。 由于这次的数字验证码图片有少量变形和倾斜,所以,可能需要积累更多的原始采样进行学习。但按照4个验证码10个数字的理论随机组合(暗含某种数字仅有少量变化,不然此组合数量还应更…

知识图谱--入门笔记

知识图谱–入门笔记-----整体的概念 1.什么是知识图谱? 描述现实世界中各个实体或者概念之间的关系,其构成一张海量的语义网络图,节点表示实体或者概念,边表示属性或者关系。 2.知识图谱中的三个节点 (1&#xff09…

【LeetCode每日一题合集】2023.7.17-2023.7.23(离线算法 环形子数组的最大和 接雨水)

文章目录 415. 字符串相加(高精度计算、大数运算)1851. 包含每个查询的最小区间⭐⭐⭐⭐⭐解法1——按区间长度排序 离线询问 并查集解法2——离线算法 优先队列 874. 模拟行走机器人(哈希表 方向数组)918. 环形子数组的最大和…

会议OA项目之会议审批(亮点功能:将审批人签名转换为电子手写签名图片)

🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于OA项目的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 一.主要功能点介绍 二.效果展示 三.前端…

AVLTree深度剖析(双旋)

在上一篇文章中我们提到了,单旋的情况(无论是左单旋还是右单旋),都仅仅适用于绝对的左边高或者绝对的右边高 b插入,高度变为h1,我们可以来试试单旋会变成什么样子 旋完之后,形成了对称关系&…

自然语言处理之AG_NEWS新闻分类

前言: 先简单说明下,关于AG_NEWS情感分类的案例,网上很多博客写了,但是要么代码有问题,要么数据集不对,要么API过时,在这里我再更新一篇博客。希望对各位同学有一定的应用效果。 1、DataSets 数据集的处理…

部署mycat2

因为mycat是Java写的,要装jdk 下载包 jdk-8u261-linux-x64.rpm 安装 安装好后,查看版本 安装mycat2 解压到data目录 修改权限 把所需的jar复制到mycat/lib目录 查看MyCat目录结构 回为mycat代理连接启动时需要有一个默认的数据源,所以我们…

C#读取写入文件的三种方式

最新对文件的操作比较频繁。这里记录一下常用的几种文件读写的方式。 我这里使用窗体来做测试&#xff0c;例子在文末&#xff0c;可下载。 1&#xff1a;二进制读写 /// <summary>/// 二进制写入文件/// </summary>private void button1_Click(object sender, E…

PuTTY连接服务器报错Connection refused

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

基于SpringBoot + Vue实现单个文件上传(带上Token和其它表单信息)的前后端完整过程

有时遇到这种需求&#xff0c;在上传文件的同时还需要带上token凭据和其它表单信息&#xff0c;那么这个需求前端可以使用FormData数据类型来实现。FormData和JSON一样也是通过body传递的&#xff0c;前者支持字符串和二进制文件&#xff0c;后者只能是字符串&#xff0c;如下图…

[CISCN 2023 初赛]go_session 解题思路过程

过程 下载题目的附件&#xff0c;是用go的gin框架写的后端&#xff0c;cookie-session是由gorilla/sessions来实现&#xff0c;而sessions库使用了另一个库&#xff1a;gorilla/securecookie来实现对cookie的安全传输。这里所谓的安全传输&#xff0c;是指保证cookie中的值不能…

STM32 USB使用记录:HID类设备(前篇)

文章目录 目的基础说明HID类演示代码分析总结 目的 USB是目前最流行的接口&#xff0c;现在很多个人用的电子设备也都是USB设备。目前大多数单片机都有USB接口&#xff0c;使用USB接口作为HID类设备来使用是非常常用的&#xff0c;比如USB鼠标、键盘都是这一类。这篇文章将简单…

向npm注册中心发布包(上)

目录 1、创建package.json文件 1.1 fields 字段 1.2 Author 字段 1.3 创建 package.json 文件 1.4 自定义 package.json 的问题 1.5 从当前目录提取的默认值 1.6 通过init命令设置配置选项 2、创建Node.js 模块 2.1 创建一个package.json 文件 2.2 创建在另一个应用程…

UE5 AI移动无动作问题

文章目录 问题背景解决方法问题背景 在使用行为树让角色移动时,出现角色行走不播放动作的情况: 解决方法 其实有2个问题导致出现这种情况 1、角色动画蓝图的问题 角色动画蓝图可能存在4个问题: ① 无播放行走动画 ② 速度的值未正常传递 ③ 播放移动动作逻辑的值判断错…

【每日一题】——C - Standings(AtCoder Beginner Contest 308 )

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;每日一题 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日反刍 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓称…

Clion开发STM32之W5500系列(DNS服务封装)

概述 在w5500基础库中进行封装&#xff0c;通过域名的方式获取实际的ip地址用于动态获取ntp的ip地址 DNS封装 头文件 /*******************************************************************************Copyright (c) [scl]。保留所有权利。****************************…

JVM对象在堆内存中是否如何分配?

1&#xff1a;指针碰撞&#xff1a;内存规整的情况下 2&#xff1a;空闲列表: 内存不规整的情况下 选择那种分配方式 是有 java堆是否规整而决定的。而java堆是否规整是否对应的垃圾回收器是否带有空间压缩整理的能力决定的。 因此当使用Serial,ParNew等带有压缩整理过程的收…

win10环境下,应用无法启动并被删除(无法完成操作,因为文件包含病毒或潜在的垃圾文件)

现象&#xff1a; 解决办法&#xff1a; 一、关闭所有自己安装的杀毒软件&#xff0c;如&#xff1a;360安全卫士&#xff0c;金山毒霸等 二、关闭win10本身的杀毒软件&#xff0c;步骤如下&#xff1a; 1、搜索栏输入“病毒和威胁防护” 2、进入以后&#xff0c;点击"病…