Background
In Rust, there are no classic constructors like in OOP languages, but there are associated functions (most frequently new) that implement the constructor pattern with explicit initialization. Associated functions allow creating struct instances with preset values or creating them with additional logic (for example, by reserving memory).
Problem
Many start using only new, forgetting about other factory method patterns (for example, with_capacity), or incorrectly implement struct initialization (especially with private/public fields), which can lead to invariant errors.
Solution
An associated function of type new is implemented through impl, and it can be the only entry point for creating objects with invariants. Functions like with_capacity provide additional capabilities, for example, to pre-allocate memory.
Example code:
pub struct MyBuffer { data: Vec<u8>, } impl MyBuffer { pub fn new() -> Self { MyBuffer { data: Vec::new() } } pub fn with_capacity(cap: usize) -> Self { MyBuffer { data: Vec::with_capacity(cap) } } }
Key features:
If new is not implemented, will Rust create it by default?
No. There is no auto-generation of new. If the method is not explicitly implemented, it will not exist, even if the struct has only public fields.
What is the fundamental difference between new and Default?
Default is a trait constructor that can only be called where the type has implemented or explicitly inherited Default. It is standard for generic algorithms but does not always coincide with new.
Can new and with_capacity methods be used for private structs?
Yes, methods can be made public or private, but creating a public constructor for a private struct does not allow users to create instances of that struct outside the module.
An open struct without invariants, all fields are public:
pub struct User { pub login: String, pub active: bool }
Pros:
Cons:
Private fields, creation only through new, invariants ensured:
pub struct User { login: String, active: bool } impl User { pub fn new(login: String) -> User { User { login, active: true } } }
Pros:
Cons: