Skip to content

new idiom: Default trait #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ language.
* [Finalisation in destructors](idioms/dtor-finally.md)
* TODO interior mutability - UnsafeCell, Cell, RefCell
* [Iterating over an `Option`](idioms/option-iter.md)
* TODO `Default` trait
* [`Default` trait](idioms/default.md)
* [Pass variables to closure](idioms/pass-var-to-closure.md)
* [`mem::replace(_)` to avoid needless clones](idioms/mem-replace.md)

Expand Down
52 changes: 52 additions & 0 deletions idioms/default.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# The `Default` Trait

## Description

Many types in Rust have a [constructor]. However, this is *specific* to the
type; Rust cannot abstract over "everything that has a `new()` method". To
allow this, the [`Default`] trait was conceived, which can be used with
containers and other generic types (e.g. see [`Option::unwrap_or_default()`]).
Notably, some containers already implement it where applicable.

Not only do one-element containers like `Cow`, `Box` or `Arc` implement
`Default` for contained `Default` types, one can automatically
`#[derive(Default)]` for structs whose fields all implement it, so the more
types implement `Default`, the more useful it becomes.

On the other hand, constructors can take multiple arguments, while the
`default()` method does not. There can even be multiple constructors with
different names, but there can only be one `Default` implementation per type.

## Example

```rust
// note that we can simply auto-derive Default here.
#[derive(Default)]
struct MyConfiguration {
// Option defaults to None
output: Option<Path>,
// Vecs default to empty vector
search_path: Vec<Path>,
// Duration defaults to zero time
timeout: Duration,
// bool defaults to false
check: bool,
}

impl MyConfiguration {
// add setters here
}
```

## See also

- The [constructor] idiom is another way to generate instances that may or may
not be "default"
- The [`Default`] documentation (scroll down for the list of implementors)
- [`Option::unwrap_or_default()`]
- [`derive(new)`]

[constructor]: ctor.md
[`Default`]: https://doc.rust-lang.org/stable/std/default/trait.Default.html
[`Option::unwrap_or_default()`]: https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.unwrap_or_default
[`derive(new)`]: https://crates.io/crates/derive-new/