我有 struct B
:
struct A {}
struct B {
a: A,
b: u32,
c: i8,
z: usize,
}
A
没有 Default
实现,也没有有意义的默认值。 b
.. z
字段都需要初始化为默认值(在本例中为 0),并且 A
将初始化为某个运行时值:let b = B {
a: some_a(),
b: 0,
c: 0,
z: 0,
};
这并不理想。更糟糕的是,如果要将
aa
添加到结构中,则需要将另一个成员添加到初始化程序中。使用 ..Default::default()
不起作用,因为 B
没有 Default
实现,因为默认情况下的任何 A
计算成本太高,无法在之后简单地丢弃。此外,无论如何我都需要在 Default
实现中使用一个非常长的结构初始化器。有没有办法将剩余的 struct 成员设置为其默认值(以便
b
将设置为 u32
的默认值)而无需写出所有成员名称?最好在添加新成员时对构造初始化程序进行最少的更改。这意味着这并不理想:
let b = B {
a: some_a(),
b: Default::default(),
c: Default::default(),
z: Default::default(),
};
最佳答案
如果你有大型结构,你可以通过派生一个构建器或构造函数来让你的生活更轻松。有一些 crate 可以做到这一点,一个流行的 crate 是 derive_builder
。
使用该 crate ,您可以执行以下操作:
use derive_builder::Builder;
// this derive will generate a struct called BBuilder
#[derive(Builder)]
struct B {
a: A,
#[builder(default = "0")]
b: u32,
#[builder(default = "0")]
c: i8,
/* ... */
#[default(default = "0")]
z: usize
}
fn main() {
let a = A { ... };
// all default values for fields b..z
let b = BBuilder::default().a(a).build().unwrap();
// or specify just some of the fields
let b = BBuilder::default()
.a(a)
.c(42)
.z(255)
.build()
.unwrap();
}
向
B
添加新字段不会影响使用 BBuilder
的代码,只要这些字段具有默认值即可。不利的一面是,如果您错过了必填字段,而不是编译错误,则会出现运行时 panic 。另一个 crate 是
derive-new
,它更简单一些。你会像这样使用它:use derive_new::new;
#[derive(new)]
struct B {
a: A,
#[new(default)]
b: u32,
#[new(default)]
c: i8,
/* ... */
#[new(default)]
z: usize
}
fn main() {
let a = A { ... };
// all default values for fields b..z
let b = B::new(a);
// To specify some of the default fields, you need to mutate
let mut b = B::new(a);
b.c = 42;
b.z = 255;
}
这不会生成任何额外的结构,它只是添加了一个
new
方法,该方法采用所有非默认参数。如果您遗漏了任何非默认字段,则会导致编译错误。
关于struct - 如何仅将某些结构成员设置为其默认值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61450798/