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:
called A::default()
1
In the 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.