【Rust】枚举(Enum)详解

Rust 枚举:类型安全的变体容器

枚举将多个相关值聚合为单一类型,各变体可携带异构数据。

1. 定义枚举

无数据枚举

rust 复制代码
enum Direction { North, South, East, West }

let dir = Direction::North;
match dir {
    Direction::North => println!("北"),
    _ => (),
}

带数据枚举

rust 复制代码
enum IpAddr { V4(String), V6(String) }

let home = IpAddr::V4("127.0.0.1".into());

2. C风格整数枚举

基础用法

rust 复制代码
#[repr(u8)]
enum Color { Red, Green, Blue }  // 默认0,1,2

enum HttpStatus { 
    Ok = 200, 
    NotFound = 404,
}

转换与FFI

rust 复制代码
// 枚举→整数
let val = Color::Green as u8;

// 整数→枚举(需验证)
fn from_u8(n: u8) -> Option<Color> {
    match n { 0 => Some(Red), 1 => Some(Green), 2 => Some(Blue), _ => None }
}

// C FFI兼容
#[repr(C)]
enum ErrorCode { Success = 0, Failed = -1 }

位标志(bitflags)

rust 复制代码
use bitflags::bitflags;
bitflags! {
    struct Perms: u32 {
        const R = 0b001; const W = 0b010; const X = 0b100;
    }
}
let p = Perms::R | Perms::W;

3. 数据变体形式

rust 复制代码
enum Message {
    Quit,                      // 无数据
    Move { x: i32, y: i32 },   // 结构体
    Write(String),             // 单值
    ChangeColor(i32,i32,i32),  // 元组
}

4. 枚举方法

rust 复制代码
impl Message {
    fn call(&self) {
        match self {
            Self::Quit => println!("退出"),
            Self::Move{x,y} => println!("移至({},{})", x, y),
            Self::Write(s) => println!("写: {}", s),
            _ => (),
        }
    }
}

5. 核心枚举:Option与Result

Option 替代空值

rust 复制代码
let some: Option<i32> = Some(5);
let none: Option<i32> = None;

fn safe_div(a: f64, b: f64) -> Option<f64> {
    if b == 0.0 { None } else { Some(a / b) }
}

Result<T,E> 处理错误

rust 复制代码
fn read_file(path: &str) -> Result<String, std::io::Error> {
    std::fs::read_to_string(path)
}

match read_file("a.txt") {
    Ok(content) => println!("{}", content),
    Err(e) => println!("错误: {}", e),
}

6. 模式匹配

match穷尽匹配

rust 复制代码
enum Coin { Penny, Nickel, Dime, Quarter(UsState) }

fn value(c: Coin) -> u8 {
    match c {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => {
            println!("来自{:?}", state);
            25
        }
    } // 必须覆盖所有变体
}

if let / while let 简化

rust 复制代码
// 替代单分支match
if let Some(3) = some_val { println!("三") }

// 条件循环
while let Some(item) = stack.pop() { println!("{}", item) }

7. 高级特性

泛型枚举

rust 复制代码
enum Either<L, R> { Left(L), Right(R) }
let num = Either::<i32, f64>::Left(42);

内存优化

rust 复制代码
enum Data { None, Int(i32), Text(String) }
println!("大小: {}", std::mem::size_of::<Data>()); // 智能压缩

实用模式

rust 复制代码
// 状态机
enum TrafficLight { Red, Yellow, Green }
impl TrafficLight {
    fn next(&self) -> Self {
        match self { Red => Green, Green => Yellow, Yellow => Red }
    }
}

8. 最佳实践速查

场景 推荐方案
可选值 Option<T>
可能失败 Result<T,E>
固定状态集 无数据枚举
异构数据 带数据枚举
C交互/标志位 C风格枚举
位操作 bitflags!

对比指南

特性 Rust风格枚举 C风格枚举
数据 可携带任意数据 仅整数
匹配 完整模式匹配 简单匹配
内存 编译器优化 固定大小
用途 状态机、复杂数据 错误码、标志位

核心优势

  • 类型安全:编译时验证所有可能性
  • 模式匹配:强制处理所有变体
  • 零成本抽象:运行时无额外开销
  • 表达力强:统一表示异构数据

枚举是Rust代数数据类型的关键,结合模式匹配,提供了超越传统枚举的强大能力。

复制代码
相关推荐
techdashen11 小时前
Pingora 的开源——Cloudflare 基于 Rust 搭建的用于替换Nginx的网络框架
nginx·rust·开源
余识-15 小时前
古竹:将时间化作最有价值的投资
金融·rust·业界资讯·tauri·投资·基金
skilllite作者17 小时前
Deer-Flow 工作流引擎深度评测报告
java·大数据·开发语言·chrome·分布式·架构·rust
alwaysrun19 小时前
Rust之数据固定Pin与Unpin
rust·编程语言
左小左19 小时前
🔥🔥🔥 我用AI基于 Tauri + Vue 3 写了个 ADB 桌面工具,把命令行的脏活全干了
android·vue.js·rust
kyriewen1120 小时前
你的前端滤镜慢得像PPT?用Rust+WebAssembly,一秒处理4K图
开发语言·前端·javascript·设计模式·rust·ecmascript·powerpoint
小杍随笔20 小时前
【Tauri 2 + Rust 配置 WebView2 缓存数据存储到安装目录】
开发语言·后端·rust·tauri
代码羊羊1 天前
Rust 迭代器完全通俗易懂指南(零基础全覆盖)
java·开发语言·rust
iDao技术魔方1 天前
DeepSeek TUI:原生 Rust 打造的终端 AI 编码 Agent
开发语言·人工智能·rust
古城小栈1 天前
封神!Rust 出品 HTTP 压测神器 cargo-whero,轻量碾压 JMeter、wrk,新手也能秒上手
jmeter·http·rust