Les structs en Rust : des supers variables
Rust n’est pas un langage orienté objet, donc on ne peut pas utiliser ni d’objet ni de classes.
À la place on va avoir ce qu’on appelle des structs
, c’est un genre de variable qui va pouvoir contenir plusieurs
champs de types différents.
Ce qu’il faut bien comprendre c’est que lorsqu’on crée un struct on crée un type de données par la même occasion.
- Un struct peut contenir plusieurs champs de types différents
- Un struct doit être créé dans le global scope
Création et Initialisation
Voici comment on définit un struct :
Maintenant voici comment on crée une instance de type User:
Si on veut print notre variable user_one il va falloir ajouter le trait Debug à notre struct de cette façon :
J’expliquerai dans un prochain article ce qu’est un trait, mais pour l’instant ce n’est pas grave si tu ne sais pas ce que c’est.
Modifier une instance de struct
Comme une instance de struct est une variable, si on la modifie il va falloir la déclarer mutable, si elle est mutable alors tous les champs sont mutables, on ne peut pas définir que certains champs mutables.
Tu vois qu’ici on a pu modifier le champ first_name de user_one avec la string “Bernie” car la variable user_one est mutable.
Les Méthodes
Les structs peuvent avoir des fonctions utilisables par une instance d’un struct, c’est ce qu’on appelle des méthodes.
Pour définir des méthodes on va d’abord utiliser le mot clé impl
qui signifie “implémenter” suivi du nom du struct,
puis on va déclarer les méthodes dans le bloc en question.
La syntaxe pour appeler une méthode est donc le nom de l’instance du struct suivi d’un .
puis le nom de la méthode.
Tu vois qu’ici on vient de créer le bloc impl Rectangle
qui contient une seule méthode, la méthode area.
Tu remarques que cette méthode prend en paramètre &self
, c’est-à-dire une référence de notre instance de struct.
On peut se demander pourquoi une référence ? Eh bien tout simplement parce que si on n’avait pas utilisé de référence
notre instance de struct serait drop
après avoir lancé la méthode area.
C’est à cause des règles de l’ownership, notre struct aurait été move car il serait passé implicitement en paramètre de la fonction area
Et oui quand on fait rec.area() en réalité on lance la méthode area avec rec en paramètre !
La syntaxe rec.area() est simplement du sucre syntaxique pour rendre plus lisible notre code, et donc étant move dans area il serait drop à la fin de area.
Fonctions associées
Les fonctions associées sont des fonctions qui se trouvent dans un bloc impl d’un struct mais qui n’ont pas besoin d’une instance de struct pour être lancés.
Donc les fonctions associées ne prendront pas &self
ou self
en paramètre.
Voici à quoi ressemble des fonctions associées :
Tu vois que la syntaxe pour appeler des fonctions associées est un peu spéciale. On utilise le nom du struct suivi
de ::
puis le nom de la fonction associée.
Les méthodes, quant à elles, sont appelées avec le .
, par exemple mon_rectangle.area()
dans l’exemple précédent
Raccourci d’initialisation d’un struct
Rust nous donne un raccourci pour créer un struct sans se répéter.
Si on veut créer un struct avec des variables qui ont le même nom que les champs on n’a pas besoin de spécifier les champs.
Comme les variables ont le même nom que les champs, on peut uniquement mettre le nom de la variable et Rust va l’assigner automatiquement au champ du même nom.
Raccourci de modification d’un struct
Un deuxième raccourci bien pratique est disponible pour les structs.
Il s’agit du raccourci de modification, cela nous permet de créer un struct en reprenant tous les champs ou seulement certains d’un autre struct.
Tu vois qu’on a créé un user_two en reprenant tous les champs de user_one SAUF le champ email que l’on a redéfini
explicitement grâce à la syntaxe ..mon_autre_struct
Ce raccourci est un gros grain de temps quand on a des structs avec beaucoup de champs et il est donc très pratique.