me'*_*me' 11 struct default rust
我有结构B:
struct A {}
struct B {
a: A,
b: u32,
c: i8,
z: usize,
}
Run Code Online (Sandbox Code Playgroud)
A没有Default实现,也没有有意义的默认值。所有字段b都z需要初始化为默认值(在本例中为 0),并将A初始化为某个运行时值:
let b = B {
a: some_a(),
b: 0,
c: 0,
z: 0,
};
Run Code Online (Sandbox Code Playgroud)
这并不理想。
更糟糕的是,如果aa要将 an 添加到结构中,则需要将另一个成员添加到初始化程序中。使用..Default::default()不起作用,因为B没有Default实现,因为A默认值中的任何 s 计算成本都太高,无法在事后简单地丢弃。此外,无论如何,我在实现中都需要一个非常长的结构初始化程序Default。
有没有什么方法可以将剩余的结构成员设置为其默认值(以便将其b设置为默认值u32)而不写出所有成员名称?
优选地,当添加新成员时,结构初始值设定项所需的更改应该最小。这意味着这并不理想:
let b = B {
a: some_a(),
b: Default::default(),
c: Default::default(),
z: Default::default(),
};
Run Code Online (Sandbox Code Playgroud)
如果您有大型结构,则可以通过派生构建器或构造函数来使您的生活更轻松。有一些板条箱可以做到这一点,其中一个流行的是derive_builder.
使用该板条箱,您可以执行以下操作:
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();
}
Run Code Online (Sandbox Code Playgroud)
只要字段具有默认值,添加新字段B就不会影响使用 的代码。BBuilder缺点是,如果您错过了必填字段,则会出现运行时恐慌,而不是编译错误。
另一个箱子是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;
}
Run Code Online (Sandbox Code Playgroud)
这不会生成任何额外的结构,它只是添加一个new方法,该方法接受所有非默认参数。如果您遗漏了任何非默认字段,则会出现编译错误。
| 归档时间: |
|
| 查看次数: |
11039 次 |
| 最近记录: |