在 Rust 里,“枚举值”这个概念实际上分成两层:
-
类型本身(
Message
); -
该类型的某个具体值(
Message::Write(String::from("hello"))
)。
“引用”枚举值时,你要分清是在“构造”它,还是在“使用/匹配”它。
一、构造一个枚举值
直接写“路径式”语法即可,不需要任何前置关键字:
let m1 = Message::Quit; // 无参变体
let m2 = Message::Move { x: 3, y: 4 }; // 结构体变体
let m3 = Message::Write(String::from("hi")); // 元组变体
此时你得到的是拥有所有权的值(m1/m2/m3
的类型就是 Message
)。
二、使用/匹配一个枚举值
拿到一个 Message
变量后,最常见的“引用”手段是 match
(或 if let
)去解构:
fn handle(msg: &Message) {
match msg {
Message::Quit => println!("bye"),
Message::Move { x, y } => println!("go to {},{}", x, y),
Message::Write(text) => println!("content: {}", text),
Message::ChangeColor(r, g, b) => println!("rgb {} {} {}", r, g, b),
}
}
要点
-
左侧的模式(
Message::Write(text)
等)用来“解构”枚举值,把内部数据绑定到新变量。 -
右侧的表达式是真正执行的代码。
-
如果只想处理某一个变体,可用
if let
:
if let Message::Write(s) = msg {
println!("just text: {}", s);
}
三、取得内部数据的“引用”还是“所有权”
-
当
msg
是&Message
(借用)时,match
得到的内部字段也是引用:
match msg {
Message::Write(ref s) => println!("borrowed: {}", s), // s: &String
// 或
Message::Write(s) => println!("moved: {}", s), // s: String,需要 msg 本身已 move
}
-
使用
ref
/ref mut
关键字可强制按引用模式匹配;不写则按 move 语义匹配。
一句话总结
“枚举值”在 Rust 里通过构造路径(Enum::Variant
)来创建,通过 match/if let 来解构/使用;解构时你可以按需拿到字段的所有权或引用。