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

复制代码
相关推荐
布列瑟农的星空9 小时前
前端都能看懂的Rust入门教程(三)——控制流语句
前端·后端·rust
Andrew_Ryan15 小时前
用 Rust 构建高性能 LiteLLM 客户端:支持流式与非流式调用
rust
魔力军16 小时前
Rust学习Day3: 3个小demo实现
java·学习·rust
Smart-Space17 小时前
htmlbuilder - rust灵活构建html
rust·html
魔力军17 小时前
Rust学习Day2: 变量与可变性、数据类型和函数和控制流
开发语言·学习·rust
暴躁小师兄数据学院1 天前
【WEB3.0零基础转行笔记】Rust编程篇-第一讲:课程简介
rust·web3·区块链·智能合约
Hello.Reader2 天前
Rocket Fairings 实战把全局能力做成“结构化中间件”
中间件·rust·rocket
Andrew_Ryan2 天前
rust arena 内存分配
rust
Andrew_Ryan2 天前
深入理解 Rust 内存管理:基于 typed_arena 的指针操作实践
rust
微小冷3 天前
Rust异步编程详解
开发语言·rust·async·await·异步编程·tokio