【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代数数据类型的关键,结合模式匹配,提供了超越传统枚举的强大能力。

复制代码
相关推荐
古城小栈16 小时前
Rust 网络请求库:reqwest
开发语言·网络·rust
WaterRun18 小时前
一个由Rust实现的, 好得多的Windows tree命令: tree++项目简介
rust·github
大厂技术总监下海18 小时前
Rust的“一发逆转弹”:Dioxus 如何用一套代码横扫 Web、桌面、移动与后端?
前端·rust·开源
superman超哥21 小时前
Rust 异步时间管理核心:Tokio 定时器实现机制深度剖析
开发语言·rust·编程语言·rust异步时间管理核心·tokio定时器实现机制·tokio定时器
古城小栈21 小时前
Rust 的 validator 库
开发语言·后端·rust
古城小栈21 小时前
Rust 的 redis-rs 库
开发语言·redis·rust
superman超哥1 天前
Rust 异步递归的解决方案
开发语言·后端·rust·编程语言·rust异步递归
Mr -老鬼1 天前
Rust 的优雅和其他语言的不同之处
java·开发语言·rust
weixin_531651811 天前
Rust 的所有权机制
java·开发语言·rust
古城小栈1 天前
Rust 丰富&好用的 格式化语法
前端·算法·rust