Utiliser Les modules en Rust
Rust fournit un système de modules puissant qui peut être utilisé pour diviser le code en unités logiques (modules) et gérer leur visibilité (publique/privée) entre elles.
Ça nous permet d’organiser notre code proprement et de nous y retrouver plus facilement.
Un module est une collection d’éléments : fonctions, structures, traits, blocs impl et même d’autres modules.
Premier Module
Pour créer un module, il suffit d’utiliser le mot clé mod
suivi du nom du module puis des accolades, tout ce qui
trouvera à l’intérieur appartiendra au module.
Donc ici on a un module demo
qui contient une fonction say_hello
.
Le soucis ici c’est que si on lance le code on a une erreur qui nous dit que la fonction est privé…
La visibilité
Par défaut tout ce qui est dans un module a une visibilité privé, c’est à dire que tout ce qui est dans le module ne pourra pas être appelé depuis l’extérieur.
Encore une fois on reconnaît ici le comportement ultra safe de Rust qui veut forcer le développeur à définir explicitement ce qui doit être accessible depuis l’extérieur pour éviter d’exposer des items qui ne devraient pas l’être.
Pour régler ce problème il suffit d’ajouter le mot clé pub
devant l’item qu’on veut utiliser depuis l’extérieur.
Les modules peuvent eux aussi contenir des modules, et encore une fois si on veut les rendre accessible il faudra ajouter le mot clé pub
devant.
Bref tu l’as compris, tout ce qui doit être appeler depuis l’extérieur du module doit être précédé du mot clé pub
La visibilité des structs
Pour les structs à l’intérieur d’un module on a un peu plus de travail…
Premièrement le struct lui même doit être accessible depuis l’extérieur, donc avoir le mot clé pub
Ensuite il va falloir préciser quel champ est accessible toujours avec le mot clé pub
.
Là tu dois te dire : “Bon okay, mais si je peux pas accéder à password, comment je fais pour instancier mon struct User ?!”
Pour cela on va utiliser une fonction associé qu’on va appeler new
et qui va générer le password automatiquement
Et voilà ! De cette façon password n’est pas accessible depuis l’extérieur MAIS on peut quand même générer une instance de User.
self et super
Le mot clé self
peut être utilisé dans un module pour indiquer qu’on utilise un item du même module, à noter que c’est optionnel car par défaut le module va chercher les items à l’intérieur de lui même.
Le mot clé super
permet d’appeler un item à dans le scope parent au module en question.
Importer d’autres fichiers
On va pouvoir importer d’autres fichiers très simplement.
Imaginons qu’on crée un fichier jack.rs
dans notre dossier src.
On va maintenant ajouter une fonction say_ciao
dans notre fichier jack.rs
et on va la rendre public pour pouvoir s’en servir dans le fichier main.rs
Et maintenant pour l’utiliser dans main.rs
il suffit d’ajouter en haut du fichier mod jack;
, cela va indiquer à Rust d’utiliser le fichier en question.
Et voilà on peut maintenant utiliser le fichier jack.rs
depuis notre fichier main.rs
!
Quand on utilise le mot clé mod
sans accolade comme dans mod jack;
Rust va automatiquement :
-
Chercher un fichier nommé
jack.rs
au même niveau que le fichier dans lequel on se trouve (ici au même niveau quemain.rs
) et l’importer afin de le rendre accessible. -
Si il ne le trouve pas il va chercher un dossier nommé
jack
et va alors chercher un fichier nommémod.rs
à l’intérieur et l’importer afin de le rendre accessible, pourquoi il va chercher un fichier mod.rs ? C’est une convetion.
Ce fichier mod.rs
va définir tous les modules utilisé par notre module actuel.
Pour illustrer ça on va créer une fichier bernie.rs
dans notre dossier jack.
Le fichier bernie va contenir la fonction qu’on veut importer :
Ensuite le fichier mod.rs
va définir les modules qu’utilise notre module jack
.
Encore une fois on doit définir les modules en public si on veut les appeler depuis l’extérieur, ici le module qu’utilise jack est bernie.
Et enfin dans main.rs
Le mot clé use
Concrètement c’est le mot clé qu’on utilise pour importer des items de librairies externes.
On peut maintenant utiliser stdout et BufWriter directement.
Le Glob opérator *
Pour importer tous les items d’un namespace dans un scope on utilise la syntaxe *
qui est appelé le global opérator.
On peut maintenant utiliser tout ce qui est contenu dans chrono::prelude directement sans être précédé de quoi que ce soit.