struct - 如何仅将某些结构成员设置为其默认值?

标签 struct rust default

我有 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/

相关文章:

c - 使用基本结构从 void* 中提取值

rust - 动态生成字符串时如何返回&str?

JAVA,无法绕过更具体的直接父类(super class)型

actionscript-3 - ActionScript – 无类型变量的默认数据类型?

css - 使用 CSS 防止默认值

c - 将结构传递给 C 中的函数

谁能解释一下,这个结构初始化实际上是如何工作的?

c - 当函数的指针存储在结构体中时如何调用函数

git - 如何让 git config ReplaceOf 与 Cargo 一起使用?

rust - 借用检查器和共享 I/O