对于具有未实现默认值的字段的结构,是否有一种简短的方法来实现默认值?
我有一个包含 20 个字段的结构:
struct StructA {
value1: i32,
value2: i32,
// ...
value19: i32,
day: chrono::NaiveDate,
}
I'd like to impl Default trait for StructA. I tried to add #[derive(Default)] to the struct, but chrono::NaiveDate doesn't implement Default.
I then tried to implement Default for StructA:
impl Default for StructA {
fn default() -> Self {
Self {
value1: Default::default(),
value2: Default::default(),
// ...
value19: Default::default(),
day: chrono::NaiveDate::from_ymd(2021, 1, 1),
}
}
}
This code works fine, but the parts of value1 through value19 are redundant. Is there a solution with less code?
- I defined
StructAto deserialize JSON data via serde-json so I can't change the struct's definition. - A value of
day: chrono::NaiveDateis always given from JSON data, so I want to avoidday: Option<chrono::NaiveDate>.
回答
该衍生箱子让这种事情轻而易举:
#[derive(Derivative)]
#[derivative(Default)]
struct StructA {
value1: i32,
value2: i32,
// ...
value19: i32,
#[derivative(Default(value = "NaiveDate::from_ymd(2021, 1, 1)"))]
day: NaiveDate,
}
如果您想避免使用外部板条箱,您的选择是:
- 您已经使用的方法,缺点是您必须命名所有字段。另请注意,您不需要
Default::default()为每个数字字段重复,一个简单的0也可以。 - 制作
day一个Option并派生Default,缺点是它将默认为None,承担运行时成本,您必须unwrap()访问它。 - 制作
day一个包装NaiveDate并实现的新类型Default以将其设置为所需的值,缺点是您需要NaiveDate通过(零成本)字段或方法访问。