diff --git a/idioms/ctor.md b/idioms/ctor.md index d9c45131..b2ab588e 100644 --- a/idioms/ctor.md +++ b/idioms/ctor.md @@ -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 { - buf: RawVec, - len: usize, -} - -impl Vec { - // Constructs a new, empty `Vec`. - // 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 { - // 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