When to use Default trait?


#1

Hi,

When I run Clippy on Rust projects it will issue a new_without_default warning for any type with a fn new() -> Self method and no implementation of Default.

I thought Default trait should be used when providing a default value is semantically required, such as SomeOptions in the document, or for writing generic code as C#'s default keyword does, but not in some arbitrary type with a no-arg constructor.

Rustonomicon even states Default trait usage is “incredibly rare” and “basically only useful for generic programming” (https://doc.rust-lang.org/nomicon/constructors.html):

While Rust provides a Default trait for specifying the moral equivalent of a default constructor,
it’s incredibly rare for this trait to be used. This is because variables aren’t implicitly
initialized. Default is basically only useful for generic programming. In concrete contexts, a
type will provide a static new method for any kind of “default” constructor.

Now I’m confused about what are the cases when implementing Default is expected.
Thanks for any suggestions.


#2

Rust documentation describes why would you use Default trait. Sufficient to say however, having new method without arguments means that you have a reasonable implementation of Default - just call that new function (or #[derive(Default)], and make new call it if new implementation is different to just putting Default values in each struct member).


#3

My understanding is that usage of Default is rare because when you deal with concrete types you usually have new or some other method that you can call explicitly to create an object. Only in generic programming you can’t do that unless you add Default requirement. This point is not really relevant to your question because it only tells you how Default is used but not when to implement it. I think Default should be implemented for any type it make sense to do so (just in case you’ll need it in generic code).

In your type cannot have a default value semantically, you shouldn’t implement Default. But such type shouldn’t have a fn new() -> Self method either because it would have the same semantic meaning as Default, if only by convention.