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