Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- [Visitor](./patterns/behavioural/visitor.md)
- [Creational](./patterns/creational/intro.md)
- [Builder](./patterns/creational/builder.md)
- [Init-Struct](./patterns/creational/init-struct.md)
- [Fold](./patterns/creational/fold.md)
- [Structural](./patterns/structural/intro.md)
- [Compose Structs](./patterns/structural/compose-structs.md)
Expand Down
66 changes: 66 additions & 0 deletions src/patterns/creational/init-struct.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Init-Struct

## Description

Construct an object relying on defaults for omitted fields.

## Example

```rust
#[derive(Debug, Default, PartialEq)]
pub struct Foo {
pub foo: Some(u32)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub foo: Some(u32)
pub foo: Option<u32>,

pub bar: String,
// Private members.
baz: Vec<u16>
// A lots more fields.
}


#[test]
fn inint_struct_test() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fn inint_struct_test() {
fn init_struct_test() {

let foo = Foo {
bar: "Some string".to_string(),
..Default::default
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
..Default::default
..Default::default()

};
}
```

## Motivation

Useful when you have a struct with a lot of fields that have well-defined/useful defaults.

## Advantages

On complex/deeply nested structs only the fields that require explicit initalization have to be
touched.

Prevents proliferation of constructors.

Can be used for one-liner initialisation as well as more complex construction.

Avoids having to write a lot of boilerplate for the common alternative, the [Builder](builder.md)
pattern.

Can still be combined with the Builder pattern if initializtion requires transformation of some
sort.

Members can still be private as long as they implement [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html).

## Disadvantages

Requires each field of the struct to implement `Default`.

I.e. if a field is missing `Default`, `default()` has to be implemented and all fields have to be set manualy to their defaults.

## Discussion

This pattern is seen frequently in Rust since you can only have a single method with a given name.
Having multiple constructors is thus less nice in Rust than it is in C++, Java, or others.

The common way to solve this is the [Builder](builder.md) pattern but this often requires a lot of
boilerplate.

## See Also

- [Init Struct Pattern](https://xaeroxe.github.io/init-struct-pattern/)