Skip to content

Commit

Permalink
[idioms/ctor] adds default constructor section
Browse files Browse the repository at this point in the history
First, I replaced the `Vec` example with `Second`. This is easier to
comprehend compared to the more complex `Vec` example. It's also
testable because it doesn't rely on `RawVec`.
  • Loading branch information
wookietreiber committed Oct 11, 2021
1 parent 66d7e6c commit 33c83d9
Showing 1 changed file with 66 additions and 25 deletions.
91 changes: 66 additions & 25 deletions idioms/ctor.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,75 @@
## Description

Rust does not have constructors as a language construct. Instead, the
convention is to use a static `new` method to create an object.

## Example

```rust,ignore
// A Rust vector, see liballoc/vec.rs
pub struct Vec<T> {
buf: RawVec<T>,
len: usize,
}
impl<T> Vec<T> {
// Constructs a new, empty `Vec<T>`.
// Note this is a static method - no self.
// This constructor doesn't take any arguments, but some might in order to
// properly initialise an object
pub fn new() -> Vec<T> {
// Create a new Vec with fields properly initialised.
Vec {
// Note that here we are calling RawVec's constructor.
buf: RawVec::new(),
len: 0,
}
convention is to use an associated `new` function to create an object:

```rust
pub struct Second {
value: u64
}

impl Second {
pub fn new(value: u64) -> Self {
Self { value }
}
}

fn main() {
let s = Second::new(42);
}
```

## Default Constructors

Rust supports default constructors with the [`Default`][std-default] trait:

```rust
pub struct Second {
value: u64
}

impl Default for Second {
fn default() -> Self {
Self { value: 0 }
}
}

fn main() {
let default = Second::default();
assert_eq!(default.value, 0);
}
```

`Default` can also be derived if all types of all fields implement `Default`,
like they do with `Second`:

```rust
#[derive(Default)]
pub struct Second {
value: u64
}

fn main() {
let default = Second::default();
assert_eq!(default.value, 0);
}
```

**Note:** When implementing `Default` for a type, it is neither required nor
recommended to also provide an associated `new` function without arguments.

**Hint:** The advantage of implementing or deriving `Default` is that your type
can now be used where a `Default` implementation is required, most prominently,
any of the [`*or_default` functions in the standard library][std-or-default].

## See also

The [builder pattern](../patterns/creational/builder.md) for constructing objects
where there are multiple configurations.
- The [default idiom](default.md) for a more in-depth description of the
`Default` trait.

- The [builder pattern](../patterns/creational/builder.md) for constructing
objects where there are multiple configurations.


[std-default]: https://doc.rust-lang.org/stable/std/default/trait.Default.html
[std-or-default]: https://doc.rust-lang.org/stable/std/?search=or_default

0 comments on commit 33c83d9

Please sign in to comment.