Rust 枚举还能这样玩?Strum 这个神级库了解一下

6、SAP HANA 建模全解析 本文全面解析了 SAP HANA 建模的核心内容,包括属性视图、分析视图和计算视图的创建与使用。文章详细介绍了建模工具的安装、不同视图类型的适用场景及操作步骤,并通过对比和案例分析帮助读者更好地理解建模流程。此外,还涵盖了建模过程中的注意事项及性能优化建议,为 SAP HANA 用户提供实用的建模指导。 阅读详情

Rust 枚举还能这样玩?Strum 这个神级库了解一下

很多 Rust 新手都知道可以通过派生宏来扩展枚举的能力,但其实 Rust 社区有一个非常流行的 Enum 增强库——Strum,通过它提供的宏能帮我们解决开发过程中很多的痛点。

当前痛点

在 Rust 中,枚举是一个非常强大的特性,很多语言里的枚举只是几个整数常量:

enum Color { RED, GREEN, BLUE };

而 Rust 的枚举不仅可以携带数据,还能用于状态机、错误处理、协议建模等场景。但还是不够方便,比如:

  • 枚举转字符串
  • 字符串转枚举
  • 遍历所有枚举值
  • …

这些功能如果自己手写,那么就需要手写很多样板代码,说实话挺麻烦的。而这时候就是强大的宏出场的时候了,接下来我们将通过一些使用场景来介绍 Strum 的用法。

首先,我们先在 Cargo.toml 添加上 strum 依赖:

[dependencies]
strum = { version = "0.28", features = ["derive"] }

场景一:枚举转字符串

有这么一个枚举:

enum Status { 
    Pending, 
    Running, 
    Finished, 
}

如果需要将枚举转换成字符串,那么一般是通过实现 Display 特征来实现:

use std::fmt;

enum Status {
    Pending,
    Running,
    Finished,
}

impl fmt::Display for Status {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Status::Pending => write!(f, "pending"),
            Status::Running => write!(f, "running"),
            Status::Finished => write!(f, "finished"),
        }
    }
}

fn main() {
    println!("{}", Status::Pending);
    println!("{}", Status::Running);
    println!("{}", Status::Finished);
}

而使用 Strum 的 Display 派生宏来实现则非常简单:

use strum::Display;

#[derive(Display)]
enum Status {
    #[strum(serialize = "pending")]
    Pending,
    #[strum(serialize = "running")]
    Running,
    #[strum(serialize = "finished")]
    Finished,
}

fn main() {
    println!("{}", Status::Pending);
    println!("{}", Status::Running);
    println!("{}", Status::Finished);
}

本质上就是 Strum 自动帮我们实现了 Display 特征,说白了就是自动生成这些样板代码。

场景二:字符串转枚举

依旧是这个枚举:

enum Status {
    Pending,
    Running,
    Finished,
}

假设我们现在需要将 pending 字符串转换为对应的枚举,那么可以通过实现 FromStr 特征来实现:

use std::str::FromStr;

#[derive(Debug)]
enum Status {
    Pending,
    Running,
    Finished,
}

impl FromStr for Status {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "pending" => Ok(Status::Pending),
            "running" => Ok(Status::Running),
            "finished" => Ok(Status::Finished),
            _ => Err("invalid".into()),
        }
    }
}

fn main() {
    println!("{:?}", "pending".parse::<Status>());
    println!("{:?}", "running".parse::<Status>());
    println!("{:?}", "finished".parse::<Status>());
}

这里可以使用 Strum 的 EnumString 派生宏来进行简化:

use strum::EnumString;

#[derive(Debug, EnumString)]
enum Status {
    #[strum(serialize = "pending")]
    Pending,
    #[strum(serialize = "running")]
    Running,
    #[strum(serialize = "finished")]
    Finished,
}

fn main() {
    println!("{:?}", "pending".parse::<Status>());
    println!("{:?}", "running".parse::<Status>());
    println!("{:?}", "finished".parse::<Status>());
}

场景三:遍历所有枚举值

一般情况下,如果我们想遍历枚举值,得专门构建出一个枚举数组来使用,比如:

fn all_status() -> Vec<Status> {
    vec![
        Status::Running,
        Status::Finished,
        Status::Cancelled,
    ]
}

其实这样挺麻烦的,万一有新增或减少枚举值,还得同步进行修改。而使用 Strum 的 EnumIter 派生宏就能解决这个问题:

use strum::{EnumIter, IntoEnumIterator};

#[derive(Debug, EnumIter)]
enum Status {
    Pending,
    Running,
    Finished,
}

fn main() {
    for status in Status::iter() {
        println!("{:?}", status);
    }
}

结语

在这篇文章里,虽然我只讲了三种用法,但是其实已经覆盖了 90% 的 Strum 使用场景了,感兴趣的读者可以自行阅读 Strum 官方文档继续探索。

不过,比起 Strum 本身,我更希望大家关注的是如何善用宏来消除重复代码。

很多 Rust 新手在学习时会下意识地避开宏,确实它很难,但你会发现宏不单是 Rust 的高级技巧,还是写出地道 Rust 代码的关键手段之一。Rust 生态中最优秀的库几乎都在使用宏写出更简洁、更安全、更易维护的代码。

华为面试手撕真题【最长不重复子串】 给定一个字符串s,请你找出其中不含有重复字符的最长子串的长度。 阅读详情

相关推荐

别再混淆了!深入浅出图解四元数姿态控制中的‘误差四元数’(附四种定义对比与仿真)

本文深入解析四元数姿态控制中的误差四元数定义差异,对比四种常见定义(如Q₀∘Q⁻¹与Q⁻¹∘Q₀)及其对PD控制性能的影响。通过刚体动力学仿真验证,揭示定义二(Q⁻¹∘Q₀)在无人机和航天器控制中的最优性能,提供工程实践建议与参数整定技巧,帮助开发者避免常见陷阱并提升控制效率。

weixin_42528191的博客 277

【亲测免费】 题目:轻松处理枚举与字符串之间的转换——推荐开源库Strum

在编程中,枚举(enum)是一种常用的数据类型,用于定义一组预设的值。而在处理字符串时,有时我们需要将枚举和字符串之间进行相互转化。Strum是一个Rust库,它提供了一系列宏和特性,使得枚举与字符串的交互变得更加简单和高效。 ### 2、项目技术分析 Strum的核心是其提供的各种宏,如`EnumString`、`Display`、`FromRepr`等,它们可以方便地实现以下功能: - *...

gitblog_00094的博客 757

VS2019 +osg3.6.5+ earth3.2+qt5.14.2+osgQt 编译教程

用vs新建工程,稍后会在写一篇博客上分享四、结语至此,所有的编译就均已完成。

king_ink的博客 1134

Strum高级用法:如何为枚举添加自定义属性与消息

Strum是一个强大的Rust库,专为枚举类型提供自定义派生功能,帮助开发者轻松为枚举添加消息、属性和其他实用功能。本文将详细介绍如何利用Strum的高级特性,为枚举类型添加自定义属性与消息,提升代码的可读性和可维护性。 ## 🌟 为什么选择Strum? 在Rust开发中,枚举(Enum)是一种非常实用的数据类型,但原生枚举缺乏一些高级功能,如自定义消息、属性和序列化支持。Strum通过提供

gitblog_01117的博客 488

实证研究之|stata清洗charls数据

stata

qq_45313933的博客 6759

从零开始:如何用PSINS工具箱构建你的第一个IMU误差模型

本文详细介绍了如何使用严恭敏教授开发的PSINS工具箱构建IMU误差模型,涵盖从基础参数设置到高级误差建模的全过程。通过imuerrset函数配置陀螺零偏、随机游走等核心参数,并结合实战案例展示消费级MEMS器件的误差建模方法,帮助用户提升惯性导航系统的精度与可靠性。

weixin_29284885的博客 322

4.3 宏:derive_builder、derive_more、strum,告别重复样板代码

本文介绍了三个实用的 Rust 派生宏库,帮助开发者减少样板代码: derive_builder:自动生成建造者模式,支持链式调用、可选字段和错误处理,比手动实现更强大。 derive_more:为新类型模式自动派生常见 trait(如 From/Into/Display 等),降低类型封装成本。 strum:增强 enum 功能,支持与字符串相互转换、遍历枚举值等元操作。 这些库能显著提升开发效率,建议在项目中优先使用它们而非手动实现类似功能。

yonggeit的博客 3056

基于R-CNN深度学习的常见手势识别系统:数据集、模型和UI界面的完整实现

卷积神经网络(CNN):用于从图像中提取特征。区域提议网络(RPN):用于生成可能包含手势的候选区域。:将候选区域调整为固定大小,并进行进一步的分类和回归。接下来,我们需要加载一个预训练的Faster R-CNN模型,并对其进行微调。我们将使用# 加载预训练的Faster R-CNN模型# 获取分类器的输入特征数# 替换分类器头部,设置为我们数据集的类别数(假设有5类手势)

YOLO 999

Strum自定义属性:EnumProperty与EnumMessage的深度应用

Strum是一个强大的Rust库,专为枚举类型添加自定义派生功能,其中EnumProperty与EnumMessage是两个核心特性,能够为枚举变体注入丰富的元数据和消息能力。本文将详细介绍这两个特性的使用方法和实际应用场景,帮助开发者充分利用Strum提升枚举类型的灵活性和可读性。 ## 快速入门:EnumMessage的基础应用 EnumMessage允许为枚举变体添加消息和文档注释,通过

gitblog_00266的博客 480

Android 14.0 首次开机默认授予app运行时权限(去掉运行时授权弹窗)

在14.0的系统rom产品定制化开发中,在6.0以后对于权限的申请,都需要动态申请,所以会在系统首次启动后,在app的首次运行时, 会弹出授权窗口,会让用户手动授予app运行时权限,在由于系统产品开发需要要求默认授予app运行时权限,不需要用户默认授予运行时弹窗,所以需要在首次开机默认授予所有app运行时权限

安卓兼职framework和app工程师的博客 2531

SAP 错误消息调试之七种武器:让所有的错误消息都能被定位

目录 长生剑 - SAPGUI Where Used List 碧玉刀 - ABAP调试器观察点 霸王枪 - ABAP调试器动态断点 多情环 - ABAP代码静态扫描 孔雀翎 - SAT 离别钩 - ST05 拳头 - 迷之方法??? Jerry在2018年开始用中文在微信公众号平台上写作之前,在SAP官方社区上总共写了639篇英文博客。 其中有一篇写于2013年介绍ABAP调试技巧的博客:

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2807

Strum与serde集成:实现无缝序列化与反序列化

Strum是一个小巧但功能强大的Rust库,专为枚举类型添加自定义派生功能而设计。当与serde结合使用时,能够实现枚举的无缝序列化与反序列化,为Rust开发者提供了便捷的数据转换解决方案。本文将详细介绍如何利用Strum与serde的强大功能,轻松处理枚举类型的序列化需求。 ## 核心功能解析:Strum如何增强枚举序列化 Strum通过自定义派生宏为枚举提供了丰富的属性控制能力,其中对se

gitblog_00033的博客 500

IIC软件协议及硬件知识汇总

IIC软件协议及硬件相关知识,真的是非常齐全了!

记得诚 1万+

Zed 图标系统设计:从 16x16 画布规范到 Rust 枚举驱动的图标管线

本文以 [crates/icons/README.md](https://link.gitcode.com/i/0df0c400d5407b29a77a4e55f805677c) 为核心,系统讲解 Zed 编辑器图标体系的设计规范、来源策略与贡献流程,并结合 [IconName 枚举](https://link.gitcode.com/i/b119a1aeb8e4594552d32cd21fff4

gitblog_01038的博客 261

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Rust Enum:从样板代码到极致精简的演进

从手写match一致性:所有枚举的转换行为完全统一,不会出现“这个枚举叫小写,那个枚举叫大写”的问题。健壮性:宏生成的代码经过社区验证,避免了手动实现时可能出现的逻辑遗漏。自解释:看到派生列表,开发者能立刻明白该枚举具备哪些能力。

咚为 364

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

rust学习(9)-关于strum crate 的简单使用

1 #[strum(to_string = “XXX”)] use strum::ToString; #[derive(ToString)] pub enum ProjectName { #[strum(to_string = "probe")] Probe, #[strum(to_string = "nspm")] Nspm, #[strum(to_string = "all")] All,

SEIZE THE DAY 525

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【Rust基础】Rust后端开发常用库

使用Rust有一段时间了,期间尝试过使用Rust做后端开发、命令行工具开发,以及做端侧模型部署,也尝试过交叉编译、FFI调用等,也算是基本入门了。在用Rust做后端接口开发时,常常会找不到一些合适库,而这些库在Java中却很常见,于是在此汇总一下后Rust后端开发中常用的一些库。

哈哈哈哈哈哈哈 1136

Rust枚举与模式匹配:核心概念与实战技巧

枚举(Enum)和模式匹配(Pattern Matching)是现代编程语言中的基础概念,通过类型系统实现数据的安全表达和处理。Rust语言将这些概念发挥到极致,其枚举是代数数据类型(ADT),能携带异构数据,而模式匹配则提供穷尽性检查确保代码安全性。这种组合在系统编程中尤为重要,能有效避免空指针异常等问题。在实际工程中,Option枚举和match表达式被广泛应用于状态管理、错误处理和API设计等场景。Rust的枚举内存布局经过特殊优化,如空指针优化(Niche Optimization),使得这种安全抽

weixin_34150830的博客 374

rust如何自动遍历结构体成员并修改值

创建自定义宏:rust// 在 macros crate 中// 解析结构体字段,生成遍历代码// 实现略...// 使用。

leijmdas的专栏 31

Hasura v3 `opendds-derive` 派生宏完全指南:为 OpenDd 类型自动实现 JSON 反序列化与 JSON Schema 生成

`opendds-derive` 是 Hasura v3 引擎(graphql-engine 仓库 `v3/` 目录)中的一个 Rust 过程宏 crate,它为 `open-dds` crate 中定义的 `OpenDd` trait 提供 `#[derive(OpenDd)]` 派生支持:只需在结构体或枚举上声明属性,即可自动获得从 JSON 值反序列化 OpenDD(Open Data Do

gitblog_01065的博客 547

Boa AST 深入解析:用 Rust 构建 ECMAScript 抽象语法树(boa_ast crate 指南)

`boa_ast`(源码位于 [core/ast](https://link.gitcode.com/i/84ae76ad877fd56d3cefb879ec9edada))是 Boa——一个用 Rust 编写的可嵌入 ECMAScript/JavaScript 引擎——的抽象语法树 crate。它依据 ECMAScript 规范的语法产生式(Parse Node)定义了一套类型安全的 AST 表

gitblog_01141的博客 997

Anki 的 Protocol Buffers 工程实践:跨语言后端接口与存储格式的设计要点

Protocol Buffers(下称 Protobuf)在 Anki 中承担双重职责:既用于 SQLite 数据库内部分数据的持久化存储格式,也用于 Python、Rust、TypeScript 三种语言之间的数据传递,充当类似"带 schema 的 JSON"的角色,但以紧凑的二进制字节形式进行序列化。本文以仓库内的 [protobuf.md](https://link.gitcode.com

gitblog_00369的博客 755

猫抓资源嗅探扩展指南:4 步把网页视频与 M3U8 流存进电脑

你是不是也遇到过这种情况:视频下完,硬盘里躺着一堆 .ts 小文件,播放器一个都打不开?或者网页视频右键另存为,发现页面播的是分片流,根本没有直链?cat-catch(猫抓)是一个免费开源的浏览器资源嗅探扩展:它把当前页面已经加载过的媒体资源记录成一张清单,勾选就能保存到本地,还自带 M3U8 合并下载,Chrome、Edge、Firefox 都能用。 ## 两种装法:应用商店或源码加载 最快

gitblog_00604的博客 73

H2O-3 交叉验证(Cross-Validation)参数全解析:从 nfolds 到早期停止自动调参

交叉验证(Cross-Validation, CV)是 H2O-3 中评估模型泛化能力、自动确定最优训练轮数的核心机制。本文以 H2O-3 官方 GBM FAQ 中的交叉验证专题为主体,结合 [h2o-core 中 `ModelBuilder` 的 CV 实现源码](https://link.gitcode.com/i/50be1a431285561b6ff43709198ccf85) 与 [参数

gitblog_00982的博客 317

LoliSnatcher性能优化10技巧:让图板浏览与下载丝般顺滑

**LoliSnatcher** 是一款支持批量下载的 booru 图板客户端,可浏览 Danbooru、Gelbooru、e621 等数十个图板站点。很多新手反馈"图多就卡、刷视频发热、下载慢",其实这些问题大多能通过设置轻松解决。本文精选 **10 个性能优化技巧**,从一键低性能模式到底层加速原理,帮你把图板浏览与下载调得丝般顺滑。 ## 性能优化速查表 | # | 技巧 | 设置位置

gitblog_01099的博客 982

开源项目 envconfig-rs 使用教程

开源项目 envconfig-rs 使用教程 项目介绍 envconfig-rs 是一个 Rust 库,旨在帮助开发者从环境变量中初始化配置结构。通过使用自定义的派生宏,envconfig-rs 可以显著减少初始化配置所需的样板代码,使得配置管理更加简洁和高效。 项目快速启动 安装 首先,在 Cargo.toml 文件中添加 envconfig 依赖: [dependencies] envconf...

gitblog_00138的博客 304
上一篇: 90% 的 Rust 新手都卡在了所有权、借用和生命周期
下一篇: Rust 错误处理的黄金搭档:一个定义错误,一个传播错误
Rust研习社
博客等级 码龄11年 51粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值