tl;dr 如何创建具有互斥字段的 record 结构?
records
procmacro 让这变得更容易一些。
use ::records;
#[records::record]
pub struct MyRecord {
a: Option<bool>,
b: Option<i32>,
}
fn main() {
let mr: MyRecord = MyRecord::new(/* either field might be Some(..), but not both*/);
match mr {
MyRecord { a: Some(_), b: None } => {},
MyRecord { a: None, b: Some(_) } => {},
_ => panic!("bad MyRecord!"),
}
}
我希望
match
语句不需要 panic
或有任何其他错误处理。或者换句话说,永远不应该出现两个字段都是 MyRecord
或两个字段都是 Some(_)
的 None
。
我想做这样的事情(人为的代码):
use ::exclusive_record_struct;
#[exclusive_record_struct]
pub struct MyRecord {
a: bool,
b: i32,
}
fn main() {
let mr: MyRecord = MyRecord::new(/* either field might be set, but not both*/);
match mr {
MyRecord { a: _ } => {},
MyRecord { b: _ } => {},
}
}
我将如何做与该代码类似的事情?
exclusive_record_struct
是一个虚构的 procmacro 示例。但是,它不需要是 procmacro。最重要的是拥有一个记录结构,它可以保证只设置一个字段。
我知道我可以使用
union
。但是,union
不提供此保证,union
也不知道哪些字段是有效的。
在 Rust 中,您可以将数据附加到枚举的变体,如下所示:
pub enum MyRecord {
A(pub bool),
B(pub i32),
}
fn main() {
let mr: MyRecord = MyRecord::A(true);
match mr {
MyRecord::A(a) => println!("Variant A, value: {a:?}"),
MyRecord::B(b) => println!("Variant B, value: {b:?}"),
}
}
参见:https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html#enum-values