聊一聊Rust的enum
enum在实际编程中是非常常用的,enum的目的就是为了清晰定义出散落在系统各个角落的相同概念的有限固定值。
一、enum介绍
如果是简单定义固定值,我们可以使用常量const。比如
public const int MAX_THREAD_COUNT=100;
在C语言中,我们可以这样定义一个枚举方便各处使用,比如:
enum Direction
{
Left,
Center,
Right
}
C#基本继承了C的enum性质,简单无别的,比如:
public enum Week{
Mon,Tue,Wed,Thu,Fri,Sat,Sun
}
当然可以加点其它,比起C要好一丢丢,然而也仅限于此。以至于当这种简单类型无法满足我们需要要扩展的时候就会使用class/struct来取代写出类似这种代码
public sealed class Error
{
public static readonly SignError=new Error(110,"sign error.");
public static readonly NetworkError=new Error(500,"network is disconnected."); public int code{get;private set;}
public string message{get;private set;} public Error(int code,string message)
{
this.code=code;
this.message=message;
}
}
这也是C#的enum鸡肋的地方。当然这并不是枚举了,只不过到达了相似效果。
接着我们来看Java的enum,就会发现它比较好一些了。还拿上面这个例子来说,比如:
public enum Error
{
SignError(110,"sign error."),NetworkError(500,"network is disconnected."); private int code;
private String message; private Error(int code,String message)
{
this.code=code;
this.message=message;
}
}
这么来看C#的变通enum和Java的原生enum能满足我们大多数的使用场景。
在rust中我们也可以声明类C这样的enum,比如:
pub enum GameState{
Wait,Running,Stop,Reboot
}
rust的enum功效不止于此,我们来看看rust的enum的奇特之处。
二、变体enum(可以当有限泛型用-个人理解)
我们可以把不同数据类型放进一个enum里,比如:
pub enum DbParameterValue<'a> {
Null,
I8(i8),
U8(u8),
I16(i16),
U16(u16),
I32(i32),
U32(u32),
I64(i64),
U64(u64),
F32(f32),
F64(f64),
String(&'a str),
StringArray(&'a [&'a str]),
U8Array(&'a [u8]),
}
pub DbParameter<'a>{
pub name:&'a str,
pub value:&'a DbParameterValue<'a>
}
pub DbSql<'a>{
pub db_parameters: Vec<DbParameter<'a>>,
...
}
可以看到rust的enum可以支持不同类型,以此到达泛型的效果,我个人把这个称作是有限泛型。
如果是C#或者Java要实现这个,就只能转换成object,这样必然触发拆箱装箱操作。
三、与match完美配合
let value=DbParameterValue::U8(100);
match value{
DbParameterValue::U8(v)=>println!("{v}"),
...
}
rust的解构操作可以直接取到实际的值,是不是很优雅。
其实整个rust体系有两个非常重要的enum:Result和Option。除了所有权和借用规则外,这两个也是保障rust安全的法宝。我们来看看它的定义
pub enum Result<T, E> {
Ok(T),
Err(E),
}
Ok(T)表示成功,并且包含返回值, T表示正确的返回值的类型(T为泛型);Err(E)表示失败,并且包含了返回值,E表示错误的返回值的类型(泛型)。
enum Option<T> {
None,
Some(T),
}
Some(T)表示元组结构体,封装了一个 T 类型的值,None表示无。
比如下面这个函数:
pub fn divide(a:i32,b:i32)->Result<i32,std::io::Error>{
if b==0{
Err(std::io::Error::new(std::io::ErrorKind::Other, "the divisor must not be ( zero )."))
} else{
Ok(a/b)
}
}
pub fn try_divide(a:i32,b:i32)->Option<i32>{
if b==0{
None
} else{
Some(a/b)
}
}
fn main(){
if let try_value=try_divide(20,100){
println!("try_value is {try_value}");
}
let value=divide(25,0);
match value{
Ok(value)=>println!("{value}"),
Err(e)=>panic!("value is {:?}", error)
}
}
从调用可以看出,我们在实际函数调用的时候经常都必须针对result和option进行处理,这也就是为什么rust没有空指针的原因,所以说rust从根上是内存安全的。当然社区针对result有更好的解决方式(?操作符配合anyhow)。网上很多例子会unwrap();但是请不要这样做,我们要保持漂亮的代码就应该尽量不使用unwrap,并且标准库中也基本使用?操作符。
四、enum的内存布局
看起来enum这么好,有没有缺点呢,缺点当然是有的,我们写个例子来看看
use std::mem::{size_of,size_of_val};
enum PValue<'a>{
U8(u8),
U64(u64),
String(&'a str),
}
fn main(){
println!("size of PValue:{}",size_of::<PValue>());
println!("size of PValue::u8:{}",size_of_val(&PValue::U8(100)));
println!("size of PValue::u64:{}",size_of_val(&PValue::U64(100)));
println!("size of PValue::str:{}",size_of_val(&PValue::String("hello rust,here's my first rust")));
}
输出结果
size of PValue:24
size of PValue::u8:24
size of PValue::u64:24
size of PValue::str:24
可以看出来,enum的内存大小是以其中最大项的内存来分配的。enum每一项都会有1byte的tag分配,当然rust编译器也有特殊优化,比如针对Option<T>就做了优化,舍弃了1byte的tag分配。
One more thing
很久没写文章了,都有点生疏了,以后还是要多练练,我发现后台插入代码居然没有rust语言可选,希望越来越好吧。
etermparser一个个人开源项目,属于个人兴趣。
https://github.com/bmrxntfj/eterm-parser
由于工作需要解析航信eterm系统返回的数据,目前部分实现了av,detr,fd,ml,pat,pnr等指令的结果解析。
有兴趣可以聊聊交个朋友^_^。
聊一聊Rust的enum的更多相关文章
- Rust入坑指南:亡羊补牢
如果你已经开始学习Rust,相信你已经体会过Rust编译器的强大.它可以帮助你避免程序中的大部分错误,但是编译器也不是万能的,如果程序写的不恰当,还是会发生错误,让程序崩溃.所以今天我们就来聊一聊Ru ...
- Rust 阴阳谜题,及纯基于代码的分析与化简
Rust 阴阳谜题,及纯基于代码的分析与化简 雾雨魔法店专栏 https://zhuanlan.zhihu.com/marisa 来源 https://zhuanlan.zhihu.com/p/522 ...
- Enum, Generic and Templates
文 Akisann@CNblogs / zhaihj@Github 本篇文章同时发布在Github上:https://zhaihj.github.io/enum-generic-and-templat ...
- Rust学习之旅(读书笔记):枚举 (Enum)
Rust学习之旅(读书笔记):枚举 (Enum) C 语言的枚举类型很弱,不如后来的语言,也不如之前的语言.在 C 语言里面枚举量就是一个名字,更方便的定义常量.今天读了<The Rust Pr ...
- 聊一聊Java的枚举enum
一. 什么是枚举 枚举是一种数据类型,具有集合的一些特点,可以存放多个元素,但存储对象有限且固定,枚举也有比较常见的使用场景,如我们需要表达性别(男.女),颜色(红.黄.蓝),星期(星期一.星期二.. ...
- Rust入门篇 (1)
Rust入门篇 声明: 本文是在参考 The Rust Programming Language 和 Rust官方教程 中文版 写的. 个人学习用 再PS. 目录这东东果然是必须的... 找个时间生成 ...
- A First Look at Rust Language
文 Akisann@CNblogs / zhaihj@Github 本篇文章同时发布在Github上:http://zhaihj.github.io/a-first-look-at-rust.html ...
- Writing A Threadpool in Rust
文 Akisann@CNblogs / zhaihj@Github 本篇文章同时发布在Github上:https://zhaihj.github.io/writing-a-threadpool-in- ...
- Rust语言学习笔记(7)
模块 // 兄弟模块 mod network { fn connect() { } } mod client { fn connect() { } } // 父子模块 mod network { fn ...
- Tokio,Rust异步编程实践之路
缘起 在许多编程语言里,我们都非常乐于去研究在这个语言中所使用的异步网络编程的框架,比如说Python的 Gevent.asyncio,Nginx 和 OpenResty,Go 等,今年年初我开始接触 ...
随机推荐
- 万字长文硬核AQS源码分析
阅读本文前,需要储备的知识点如下,点击链接直接跳转. java线程详解 Java不能操作内存?Unsafe了解一下 一文读懂LockSupport AQS简介 AQS即AbstractQueuedSy ...
- Python 潮流周刊#17:Excel 终于支持 Python 了、Meta 重磅开源新项目、Mojo 新得 1 亿美元融资
你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.标题取自其中两则分享,不代表全部内容都是该主题,特此声明. 本周刊由 Python猫 出品,精心筛选国内外的 25 ...
- mac安装nvm
系统:macos catalina版本:10.15.7 一.安装nvm 打开终端执行这个命令 安装的版本是 v0.39.1 curl -o- [https://raw.githubuserconten ...
- MySQL实战实战系列 03 事务隔离:为什么你改了我还看不见?
提到事务,你肯定不陌生,和数据库打交道的时候,我们总是会用到事务.最经典的例子就是转账,你要给朋友小王转 100 块钱,而此时你的银行卡只有 100 块钱. 转账过程具体到程序里会有一系列的操作,比如 ...
- 支持JDK19虚拟线程的web框架,之四:看源码,了解quarkus如何支持虚拟线程
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<支持JDK19虚拟线程的web ...
- 使用shuffle sharding增加容错性
使用shuffle sharding增加容错性 最近在看kubernetes的API Priority and Fairness,它使用shuffle sharding来为请求选择处理队列,以此防止高 ...
- 彻底解决Chrome“请停用以开发者模式运行的扩展程序”提示(亲测整合)
本站有大佬已写较全的解决方案(修改dll文件法) 原文链接 但是本人Chrome76版本不适用,匹配不到提示语,在知乎中找到修改注册表的方法可以解决 原文链接 最后附上一个谷歌访问助手吧 链接: ht ...
- Redis系列24:Redis使用规范
Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...
- 前端三件套系例之JS——JS的BOM操作、JS的DOM操作
文章目录 1 JS的BOM操作 1.介绍 2.window对象 2-1 代码 3.window的子对象 3-1 navigator对象(了解即可) 3-2 screen对象(了解即可) 3-3 his ...
- QQ机器人整理合集
QQ机器人有什么用呢? QQ机器人可以实现包括自动回复.定时推送.发送图片QQ机器人,营销圈用的比较多,可以开发各种自动功能等等.用其制作的QQ机器人程序 机器人框架+插件 小栗子机器人 官网:htt ...