When Default makes sense
Implement Default for a type that has an obvious neutral value — empty collections, zero numbers, Some-vs-None as None. Don't implement it just because the compiler nudges you to; if there's no obviously-correct default, leave it out and force callers to construct values explicitly.
Deriving Default
`#[derive(Default)]` works if every field implements Default. For enums, the `#[default]` attribute on a variant in Rust 1.62+ picks which variant is the default. For structs with one or two fields that need an explicit default, implement Default by hand — it's short.
For deeper background, see a complete cheat-sheet of std collection complexities for the broader context behind this section.
Default in struct update syntax
`Config { logging: true, ..Default::default() }` is the canonical way to construct a struct with mostly-default values. Combined with `#[derive(Default)]` on the struct, this gives builder-like ergonomics with no boilerplate.
Default for generic parameters
Functions can constrain a generic parameter with `T: Default` to call `T::default()`. The `Vec<T>::new()` and `HashMap::new()` constructors use this to produce empty collections without requiring you to spell out the element type.
For deeper background, see the official Rust API guidelines for module-level design for the broader context behind this section.
Common pitfalls
`Default` is sometimes confused with "sensible config" — but the distinction matters. A `LogLevel::default()` of Info is a config decision; encoding it in the Default impl couples the type to that policy. For configurable defaults, prefer a separate `Config::default_for_production()` method.