我有一个struct Foo
,它表示一种外部序列化格式.Foo
有几十个字段,并且一直在添加更多字段.幸运的是,所有新字段都保证有合理的默认值.
Rust有一个很好的语法,可以使用默认值创建 struct ,然后更新一些选定的值:
Foo {
bar: true,
..Default::default()
}
类似地,我们可以使用类型为PhantomData
的私有字段来表示"此 struct 在future 版本中可能有更多字段"的 idea .
但是如果我们把这两个习语结合起来,我们会得到一个错误:
use std::default::Default;
mod F {
use std::default::Default;
use std::marker::PhantomData;
pub struct Foo {
pub bar: bool,
phantom: PhantomData<()>,
}
impl Default for Foo {
fn default() -> Foo {
Foo {
bar: false,
phantom: PhantomData,
}
}
}
}
fn main() {
F::Foo {
bar: true,
..Default::default()
};
}
这给了我们一个错误:
error: field `phantom` of struct `F::Foo` is private [--explain E0451]
--> <anon>:23:5
|>
23 |> F::Foo {
|> ^
从逻辑上讲,我认为这应该是可行的,因为我们只更新公共字段,这将是一个有用的习惯用法.另一种 Select 是支持以下内容:
Foo::new()
.set_bar(true)
...这会让几十个字段变得单调乏味.
我如何解决这个问题?