#9 Structs
struct, impl, méthodes
Définir des structs
Une struct (structure) permet de regrouper des données liées sous un même nom. C'est l'outil principal pour créer des types personnalisés en Rust.
struct Rectangle {
largeur: u32,
hauteur: u32,
}Chaque champ a un nom et un type. Par convention, les noms de structs sont en PascalCase et les noms de champs en snake_case.
Créer des instances
Pour créer une instance, on spécifie une valeur pour chaque champ :
let rect = Rectangle {
largeur: 30,
hauteur: 50,
};
println!("Rectangle : {} x {}", rect.largeur, rect.hauteur);On accède aux champs avec la notation pointée. Rust offre aussi une syntaxe raccourcie quand le nom de la variable correspond au nom du champ :
fn creer_rectangle(largeur: u32, hauteur: u32) -> Rectangle {
Rectangle {
largeur, // Raccourci : équivaut à largeur: largeur
hauteur,
}
}
// Créer une struct à partir d'une autre
let rect2 = Rectangle {
largeur: 10,
..rect // Copie les champs restants depuis rect
};Méthodes avec impl
Les méthodes sont des fonctions attachées à une struct. On les définit dans un bloc impl. Le premier paramètre est toujours &self (ou &mut self pour modifier).
impl Rectangle {
fn aire(&self) -> u32 {
self.largeur * self.hauteur
}
fn peut_contenir(&self, autre: &Rectangle) -> bool {
self.largeur > autre.largeur && self.hauteur > autre.hauteur
}
}
fn main() {
let rect1 = Rectangle { largeur: 30, hauteur: 50 };
let rect2 = Rectangle { largeur: 10, hauteur: 40 };
println!("Aire : {} pixels carrés", rect1.aire());
println!("Peut contenir rect2 : {}", rect1.peut_contenir(&rect2));
}&self est un raccourci pour self: &Self, où Self est un alias pour le type de la struct. La méthode emprunte l'instance sans en prendre possession.
Fonctions associées
Les fonctions dans un bloc impl qui ne prennent pas self en paramètre sont des fonctions associées. On les appelle avec ::. Elles servent souvent de constructeurs.
impl Rectangle {
fn carre(taille: u32) -> Self {
Self {
largeur: taille,
hauteur: taille,
}
}
}
fn main() {
let c = Rectangle::carre(25);
println!("Créé un carré de {}x{}", c.largeur, c.hauteur);
}String::from() que vous avez déjà utilisé est exactement ce type de fonction associée.
Tuple structs
Les tuple structs sont des structs dont les champs n'ont pas de nom. Elles sont utiles pour créer des types distincts à partir de tuples.
struct Color(u8, u8, u8);
struct Point(f64, f64, f64);
fn main() {
let orange = Color(255, 128, 0);
let origine = Point(0.0, 0.0, 0.0);
println!("Couleur : Color({}, {}, {})", orange.0, orange.1, orange.2);
// Color et Point sont des types différents,
// même si leur structure est similaire
}On accède aux champs par leur index (.0, .1, etc.). L'avantage par rapport à un simple tuple : Color et Point sont des types distincts, même s'ils ont la même structure interne.
À vous de jouer
Essayez les commandes ci-dessous pour travailler avec des structs :