Historique de la question
En Rust, il n'y a pas de constructeurs classiques comme dans les langages de programmation orientée objet, mais il existe des fonctions associées (le plus souvent new) qui mettent en œuvre le motif des constructeurs avec initialisation explicite. Les fonctions associées permettent de créer des instances de structures avec des valeurs prédéfinies ou de les créer avec une logique supplémentaire (par exemple, avec une réservation de mémoire).
Problème
Beaucoup commencent à utiliser uniquement new, oubliant d'autres motifs de méthodes de fabrique (comme avec with_capacity), ou mettent mal en œuvre l'initialisation des structures (surtout avec des champs privés/publics), ce qui peut conduire à des erreurs d'invariants.
Solution
Une fonction associée de type new est mise en œuvre via impl, elle peut être le seul point d'entrée pour la création d'objets avec des invariants. Des fonctions comme with_capacity offrent des possibilités supplémentaires, par exemple, allouer de la mémoire à l'avance.
Exemple de 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) } } }
Caractéristiques clés :
Si je ne mets pas en œuvre new, Rust en générera-t-il un par défaut ?
Non. Il n'y a pas de génération automatique de new. Si la méthode n'est pas explicitement mise en œuvre, elle n'existera pas, même si la structure n'a que des champs publics.
Quelle est la différence fondamentale entre new et Default ?
Default est un constructeur de traits qui ne peut être appelé que là où le type a mis en œuvre ou hérité explicitement de Default. Il est standard pour les algorithmes génériques, mais ne coïncide pas toujours avec new.
Peut-on utiliser les méthodes new et with_capacity pour des structures privées ?
Oui, les méthodes peuvent être publiques ou privées, mais créer un constructeur public pour une structure privée ne permet pas aux utilisateurs de créer des instances de cette structure en dehors du module.
Structure ouverte sans invariants, tous les champs sont publics :
pub struct User { pub login: String, pub active: bool }
Avantages :
Inconvénients :
Champs privés, création uniquement via new, invariants assurés :
pub struct User { login: String, active: bool } impl User { pub fn new(login: String) -> User { User { login, active: true } } }
Avantages :
Inconvénients :