SebastianJL
SebastianJL

Reputation: 219

How does Default::default() work in rust?

Just to clarify, I am not asking how to use the Default trait or how to implement it. What I am wondering is how a line like

let a: f32 = Default::default();

actually works? What is the implementation of Default::default()?

I would imagine something like this

fn default<T: Default>() -> T {
    T::default()
}

I don't even really know what to search for since this seems to be an associated function to a Trait? Is this a thing? Anyways, I can't find it in the docs of std::default so I'm kind of stumped.

Upvotes: 3

Views: 2089

Answers (3)

Locke
Locke

Reputation: 8980

In this context, all of these lines are equivalent. Default is a trait implemented by f32 which contains the function fn default() -> Self. Essentially we are just telling the compiler that we want to invoke that trait. There might be other traits with a function default so this prevents ambiguity.

// Explicitly invoke the f32 implementation of Default.
let a: f32 = Default::default();
let a = <f32 as Default>::default();

// Call the function default for f32 which is resolved to be the trait Default.
let a = f32::default();

That being said, f32::default() would be preferred in almost all cases since it better expresses what you are trying to do. f32 does not provide a default function on its own and it would be strange if there was a competing trait imported to the module. If that were the case, <f32 as Default>::default() is better since it explicitly states which trait implementation of which type we are invoking the function default for. Lastly, Default::default() can be an easy alternative since it lets the compiler infer the type based on context, but is generally discouraged since it can make your code less explicit.

Upvotes: 4

Chayim Friedman
Chayim Friedman

Reputation: 71380

Default::default() is just <_ as Default>::default(), i.e. "use inference to find the type".

Upvotes: 4

Thomas
Thomas

Reputation: 181998

To add to @Locke's excellent answer, here's what the implementation of Default for f32 could look like:

impl Default for f32 {
    fn default() -> Self {  // Or f32 instead of Self, same thing.
        0.0f32
    }
}

Upvotes: 1

Related Questions