我有一些结构与重叠和唯一的字段。现在,我用不同结构体的枚举来处理这个问题,如下所示。这使得访问共享字段变得很麻烦,而在确定类型之后,更容易继续处理特定字段:
pub struct MyStructA {
pub a: u64,
pub b: u64,
pub c: u64,
pub d: u64,
}
pub struct MyStructB {
pub a: u64,
pub b: u64,
pub e: String,
pub f: String,
}
pub enum MyStructEnum {
Num(MyStructA),
Str(MyStructB),
}
// This gets annoying with many shared fields
pub fn get_a(m: MyStructEnum) -> u64 {
match m {
MyStructEnum::Num(n) => n.a,
MyStructEnum::Str(s) => s.a,
}
}
// When we know m is MyStructB this is easy
pub fn work_on_b(m: MyStructB) {
println!("{} {}", m.a, m.e)
因为我有许多重叠的字段和更多不同的类型来维护get_a()
类函数会很累,并且假设结构像c中那样布局似乎很愚蠢。
所以我可以输入
pub struct NewStructA {
pub c: u64,
pub d: u64,
}
pub struct NewStructB {
pub e: String,
pub f: String,
}
pub enum NewStructEnum {
Num(NewStructA),
Str(NewStructB),
}
pub struct NewStruct {
pub a: u64,
pub b: u64,
pub e: NewStructEnum,
}
// Now this is easy
pub fn new_get_a(n: NewStruct) -> u64 {
n.a
}
// But now I can't access a after identifying the type B
pub fn work_on_b(m: NewStructB) {
println!("{} {}", m.a, m.e)
}
有什么方法可以两全其美吗?在C语言中,这很容易(而且不安全)。
可以使用基结构体,但是在枚举中。即:
pub struct NewStruct {
pub a: u64,
pub b: u64,
}
pub struct NewStructA {
base: NewStruct,
pub c: u64,
pub d: u64,
}
pub struct NewStructB {
base: NewStruct,
pub e: String,
pub f: String,
}
pub enum NewStructEnum {
Num(NewStructA),
Str(NewStructB),
}
现在您可以为base
定义一个访问器函数:
pub fn base(v: &NewStructEnum) -> &NewStruct {
match v {
NewStructEnum::Num(NewStructA { base, .. }) => base,
NewStructEnum::Str(NewStructB { base, .. }) => base,
}
}
访问公共域与base(&s).a
一样容易。您可能还需要创建base_mut()
。当然,当有对具体类型的引用时,仍然可以访问字段。
虽然不如C语言好,但还是很不错的。