Rust模式匹配中如何将变量绑定到枚举变体?
Rust模式匹配中绑定枚举变体并直接访问其字段
你在匹配A::A1时,想绑定内部的B::B1变体并直接访问它的num字段,但当前绑定的b是B枚举类型,没法直接访问变体专属字段,又不想手动解构所有字段——下面几种方法可以帮你保留对B::B1变体的引用或绑定,同时便捷访问字段:
方案1:分支内局部解构(字段较多时首选)
外层match已经确保b是B::B1变体,所以可以在分支里用let只解构你需要的字段,其他字段用..忽略,完全不用全部写出来:
enum A { A1(B) } enum B { B1 { num: u64, name: String, // 哪怕有更多字段也不用管 } } fn main() { let a = A::A1(B::B1 { num: 123, name: "demo".into() }); match a { A::A1(b @ B::B1 { .. }) => { // 只取需要的num,其他字段忽略 let B::B1 { num, .. } = b; println!("num: {}", num); // 这里还能正常使用b变量 println!("b 确实是 B::B1 变体"); } } }
方案2:匹配时同时绑定变体与字段
如果需要的字段很少,直接在模式里同时绑定变体和目标字段就行,一步到位:
fn main() { let a = A::A1(B::B1 { num: 123 }); match a { // 同时拿到b变体和num字段 A::A1(b @ B::B1 { num }) => { println!("num: {}", num); // 后续仍可使用b } } }
方案3:用let-else明确语义(Rust 1.53+)
要是想更清晰地表达“这里肯定是B::B1”的逻辑,用let-else配合unreachable!()就行,不会有编译警告:
fn main() { let a = A::A1(B::B1 { num: 123 }); match a { A::A1(b @ B::B1 { .. }) => { let B::B1 { num, .. } = b else { // 外层match已经筛过,这里永远不会执行 unreachable!(); }; println!("num: {}", num); // b变量依然可用 } } }
方案4:绑定变体的引用(保留原所有权)
如果不想转移b的所有权,只想获取变体的引用,加个ref关键字就行:
fn main() { let a = A::A1(B::B1 { num: 123 }); match a { A::A1(ref b @ B::B1 { .. }) => { let B::B1 { num, .. } = b; println!("num: {}", num); // b是&B类型,原a的所有权还在 } } }
内容的提问来源于stack exchange,提问作者Yuri Geinish
相关产品推荐
相关产品推荐

