copied successfully!
Explain an obscure behavior of the Default trait
What is the expected outcome of the following example?
struct A { i: i32, } impl Default for A { fn default() -> Self { println!("called A::default()"); A { i: 42 } } } #[derive(Default)] struct B { a: A, i: i32, } impl B { fn new(a: A) -> Self { B { a, ..Default::default() } } } fn main() { let a = A { i: 1 }; let b = B::new(a); println!("{}", b.a.i); }
The expected output of this example is:
In thecalled A::default() 1
main
function, an instance of A
is created with i
being 1
. This is passed to B::new
function to create an instance of B
. Inside B::new
, the struct update syntax ..Default::default()
is used, which sets the default value for fields of B
that are not explicitly specified. However, since a
is already specified with the A
instance created in main
, A::default()
is actually not used to give a value to the field a
. As a result, b.a.i
remains as 1
.
However, while creating the instance of B
, since i
is not specified, Default::default
will be called for it, which in the case of i32
will make it 0
. Also, since A::default()
is part of the Default::default
for the B
struct (although not used in this particular instance), it will also be called. This is why you see the "called A::default()" message. But the value 42
from A::default()
is not used for b.a.i
in this instance.