3

I have a generic struct and want to provide a concrete default implementation which will also allow user to override a value of the default field, but am getting compile errors:

struct MyStruct<A, B, C> {
    pub a: A,
    pub b: B,
    pub c: C,
}

impl<A, B, C> MyStruct<A, B, C>
where
    A: Trait1,
    B: Trait2,
    C: Trait3,
{
    pub fn foo() {}
}

trait Trait1 {}
trait Trait2 {}
trait Trait3 {}

I can create instances of MyStruct explicitly:

struct SomeA();
impl Trait1 for SomeA {}
struct SomeB();
impl Trait2 for SomeB {}
struct SomeC();
impl Trait3 for SomeC {}

let a = SomeA();
let b = SomeB();
let c = SomeC();

let my_struct = MyStruct { a: a, b: b, c: c }; // compiles

Now I want to implement Default which will also allow overriding a particular field with a different value when necessary (allow partial default?). Not sure on the syntax:

impl Default for MyStruct<SomeA, SomeB, SomeC> {
    fn default() -> Self {
        ...
    }
}

Playground

trent
  • 25,033
  • 7
  • 51
  • 90
Avba
  • 14,822
  • 20
  • 92
  • 192
  • I'm not completely sure what you mean by "override a value of the default field". `Default::default` doesn't take any arguments, so you can't pass anything in, but since all the fields of `MyStruct` are `pub` you can use the not-super-well-known [struct update syntax](https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax), like `MyStruct { a: SomeA(), ..Default::default() }`. It would help if you give an example of how you want to use this "partial default". – trent Oct 18 '20 at 14:13
  • [Is there a faster/shorter way to initialize variables in a Rust struct?](/q/19650265/3650362) is the question about struct update syntax that I couldn't find to link to earlier – trent Oct 18 '20 at 15:49

1 Answers1

5

You can achieve this by only implementing Default if A, B, and C all implement Default:

impl <A, B, C> Default for MyStruct<A, B, C> where A: Default, B: Default, C: Default {
    fn default() -> Self {
        Self {
            a: A::default(),
            b: B::default(),
            c: C::default(),
        }   
    }   
}
Daniel Wagner-Hall
  • 2,446
  • 1
  • 20
  • 18