Rust中Strum庫實現(xiàn)枚舉
很多 Rust 新手都知道可以通過派生宏來擴展枚舉的能力,但其實 Rust 社區(qū)有一個非常流行的 Enum 增強庫——Strum,通過它提供的宏能幫我們解決開發(fā)過程中很多的痛點。
當前痛點
在 Rust 中,枚舉是一個非常強大的特性,很多語言里的枚舉只是幾個整數(shù)常量:
enum Color { RED, GREEN, BLUE };
而 Rust 的枚舉不僅可以攜帶數(shù)據(jù),還能用于狀態(tài)機、錯誤處理、協(xié)議建模等場景。但還是不夠方便,比如:
- 枚舉轉(zhuǎn)字符串
- 字符串轉(zhuǎn)枚舉
- 遍歷所有枚舉值
- ...
這些功能如果自己手寫,那么就需要手寫很多樣板代碼,說實話挺麻煩的。而這時候就是強大的宏出場的時候了,接下來我們將通過一些使用場景來介紹 Strum 的用法。
首先,我們先在 Cargo.toml 添加上 strum 依賴:
[dependencies]
strum = { version = "0.28", features = ["derive"] }
場景一:枚舉轉(zhuǎn)字符串
有這么一個枚舉:
enum Status {
Pending,
Running,
Finished,
}
如果需要將枚舉轉(zhuǎn)換成字符串,那么一般是通過實現(xiàn) Display 特征來實現(xiàn):
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 派生宏來實現(xiàn)則非常簡單:
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);
}
本質(zhì)上就是 Strum 自動幫我們實現(xiàn)了 Display 特征,說白了就是自動生成這些樣板代碼。
場景二:字符串轉(zhuǎn)枚舉
依舊是這個枚舉:
enum Status {
Pending,
Running,
Finished,
}
假設(shè)我們現(xiàn)在需要將 pending 字符串轉(zhuǎn)換為對應(yīng)的枚舉,那么可以通過實現(xiàn) FromStr 特征來實現(xiàn):
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>());
}
場景三:遍歷所有枚舉值
一般情況下,如果我們想遍歷枚舉值,得專門構(gòu)建出一個枚舉數(shù)組來使用,比如:
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);
}
}
結(jié)語
在這篇文章里,雖然我只講了三種用法,但是其實已經(jīng)覆蓋了 90% 的 Strum 使用場景了,感興趣的讀者可以自行閱讀 Strum 官方文檔繼續(xù)探索。
不過,比起 Strum 本身,我更希望大家關(guān)注的是如何善用宏來消除重復(fù)代碼。
很多 Rust 新手在學(xué)習(xí)時會下意識地避開宏,確實它很難,但你會發(fā)現(xiàn)宏不單是 Rust 的高級技巧,還是寫出地道 Rust 代碼的關(guān)鍵手段之一。Rust 生態(tài)中最優(yōu)秀的庫幾乎都在使用宏寫出更簡潔、更安全、更易維護的代碼。
到此這篇關(guān)于Rust中Strum庫實現(xiàn)枚舉的文章就介紹到這了,更多相關(guān)Rust Strum枚舉內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust中多線程?Web?服務(wù)器的項目實戰(zhàn)
本文主要介紹了Rust中多線程?Web?服務(wù)器的項目實戰(zhàn),利用通道和互斥鎖管理任務(wù)隊列,解決單線程處理請求的性能瓶頸,確保并發(fā)處理能力并實現(xiàn)優(yōu)雅關(guān)閉機制2025-06-06
前端基于Rust實現(xiàn)的Wasm進行圖片壓縮的技術(shù)文檔(實現(xiàn)方案)
在現(xiàn)代Web開發(fā)中,利用Rust編寫的圖片壓縮代碼可以編譯成WebAssembly(Wasm)模塊,Rust的內(nèi)存安全特性和Wasm的跨平臺能力,使得這種方案既高效又安全,對Rust?Wasm圖片壓縮實現(xiàn)方案感興趣的朋友一起看看吧2024-09-09
Rust初體驗:手把手教你構(gòu)建‘Hello,?World!’
"準備好了嗎?一起踏上Rust編程語言的精彩旅程!在這篇「Rust初體驗」中,我們將手把手教你構(gòu)建經(jīng)典程序“Hello,?World!”,感受Rust的強大與安全,短短幾行代碼,就能讓你對這個系統(tǒng)級語言的魅力一探究竟!快加入吧,驚喜等你發(fā)現(xiàn)!"2024-01-01
Rust可迭代類型迭代器正確創(chuàng)建自定義可迭代類型的方法
在 Rust 中, 如果一個類型實現(xiàn)了 Iterator, 那么它會被同時實現(xiàn) IntoIterator, 具體邏輯是返回自身, 因為自身就是迭代器,這篇文章主要介紹了Rust可迭代類型迭代器正確創(chuàng)建自定義可迭代類型的方法,需要的朋友可以參考下2023-12-12

