【问题标题】:Only setting one field in a Rust `Default` implementation [duplicate]仅在 Rust `Default` 实现中设置一个字段 [重复]
【发布时间】:2021-10-25 18:21:21
【问题描述】:

我有一个 Rust struct 有大量字段,所有这些字段本身都是 Default。我想为它创建一个自定义的impl Default,具有以下语义:

  1. 其中一个字段具有自定义值
  2. 所有其他字段的值均来自其Default::default

我希望这样做:

impl Default for Foo {
    fn default() -> Self {
        Self {
            thing: 2,
            ..Default::default()
        }
    }
}

...但这实际上会导致未经检查的递归,因为..Default::default()Self 的每个成员调用Self::default() 而不是$member::default()

除了编写自定义宏或明确列出每个字段之外,有什么方法可以做到这一点?

【问题讨论】:

  • 好吧,您可以自己编写默认值。借助一些 IDE 或工具应该是几秒钟的事情。宏也可以,但是如何区分不想添加到扩展中的字段?
  • "除了编写自定义宏或显式列出每个字段之外,有什么方法可以做到这一点?" 因为#[derive(Default)] 本身就是一个列出每个字段的宏field: Default::default(),可能没有更好的方法了。

标签: rust traits


【解决方案1】:

您可以use the derivative crate 来实现这一点。它提供了一些标准库派生宏的替代版本,具有额外的可定制性:

#[derive(Debug, Derivative)]
#[derivative(Default)]
struct Foo {
    foo: u8,
    #[derivative(Default(value="2"))]
    thing: u8,
}

只需使用标准库,您既可以派生Default 以获取所有字段的默认值,也可以完全手动实现。

【讨论】:

  • 这个真的很方便
  • 这看起来正是我想要的,谢谢!当我允许时会接受。
猜你喜欢
  • 2011-03-10
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多