Achtergrond
In Rust zijn er geen klassieke constructeurs zoals in OOP-talen, maar er zijn geassocieerde functies (meestal new) die de constructormethode met expliciete initiatie implementeren. Geassocieerde functies maken het mogelijk om structuren te maken met vooraf ingestelde waarden of ze te creëren met aanvullende logica (bijvoorbeeld met geheugenreservatie).
Probleem
Veel mensen beginnen alleen new te gebruiken en vergeten andere patronen van fabrieksmethoden (zoals with_capacity), of implementeren het initialiseren van structuren verkeerd (vooral met private/publieke velden), wat kan leiden tot invariantiefouten.
Oplossing
Een geassocieerde functie zoals new wordt geïmplementeerd via impl, en kan de enige toegangspunt zijn voor het creëren van objecten met invarianten. Functies zoals with_capacity bieden extra mogelijkheden, zoals het vooraf toewijzen van geheugen.
Voorbeeldcode:
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) } } }
Belangrijke kenmerken:
Als je new niet implementeert, creëert Rust deze dan standaard?
Nee. Er is geen automatische generatie van new. Als de methode niet expliciet is geïmplementeerd, is deze er niet, zelfs als de structuur alleen publieke velden heeft.
Wat is het fundamentele verschil tussen new en Default?
Default is een trait-constructor die alleen kan worden aangeroepen waar het type Default implementeert of expliciet heeft geërfd. Het is standaard voor generieke algoritmen, maar komt niet altijd overeen met new.
Kan je de methoden new en with_capacity gebruiken voor private structuren?
Ja, methoden kunnen publiek of privé worden gemaakt, maar het maken van een publieke constructeur voor een private structuur stelt gebruikers niet in staat om instanties van deze structuur buiten de module te maken.
Open structuur zonder invarianten, alle velden zijn publiek:
pub struct User { pub login: String, pub active: bool }
Voordelen:
Nadelen:
Velden zijn privé, creatie alleen via new, invarianten zijn gewaarborgd:
pub struct User { login: String, active: bool } impl User { pub fn new(login: String) -> User { User { login, active: true } } }
Voordelen:
Nadelen: