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

复制代码
相关推荐
唐装鼠4 小时前
Rust 类型转换语法大全(deepseek)
rust
ServBay8 小时前
7个Rust写法让代码干净卫生又高效
后端·rust
Source.Liu10 小时前
【Rust】变量系统详解
rust
Source.Liu12 小时前
【Rust】数组与向量:集合类型全解
rust
唐装鼠12 小时前
Rust Box<T> 和引用(deepseek)
开发语言·rust
Source.Liu12 小时前
【Rust】结构体(Struct)详解
rust
isyuah14 小时前
Miko v0.7 发布:我写的一个 Rust Web 框架,虽然还是个玩具
后端·rust
isyuah14 小时前
Miko 框架系列(十四):集成测试
后端·rust
唐装鼠14 小时前
Rust Turbofish 语法详解(deepseek)
开发语言·后端·rust