The Default
trait supports the following attributes:
You can use derivative to derive a default implementation on enumerations! This does not work with rustc's #[derive(Default)]
. All you need is to specify what variant is the default value:
#[derive(Debug, Derivative)] #[derivative(Default)] enum Enum { A, #[derivative(Default)] B, } println!("{:?}", Enum::default()); // B
You can use derivative to change the default value of a field in a Default
implementation:
#[derive(Debug, Derivative)] #[derivative(Default)] struct Foo { foo: u8, #[derivative(Default(value="42"))] bar: u8, } println!("{:?}", Foo::default()); // Foo { foo: 0, bar: 42 }
new
functionYou can use derivative to derive a convenience new
method for your type that calls Default::default
:
#[derive(Debug, Derivative)] #[derivative(Default(new="true"))] struct Foo { foo: u8, bar: u8, } println!("{:?}", Foo::new()); // Foo { foo: 0, bar: 0 }
The following does not work because derive
adds a T: Default
bound on the impl Default for Foo<T>
:
#[derive(Default)] struct Foo<T> { foo: Option<T>, } struct NonDefault; Foo::<NonDefault>::default() // gives: // error: no associated item named `default` found for type `Foo<NonDefault>` in the current scope // = note: the method `default` exists but the following trait bounds were not satisfied: `NonDefault : std::default::Default`
That bound however is useless as Option<T>: Default
for any T
. derivative
allows you to explicitly specify a bound if the inferred one is not correct:
#[derive(Derivative)] #[derivative(Default(bound=""))] // don't need any bound struct Foo<T> { foo: Option<T>, } struct NonDefault; Foo::<NonDefault>::default() // works!