Recherche…
Syntaxe
- mod modname ; // Recherche le module dans modname .rs ou modname /mod.rs dans le même répertoire
- mod modname { block }
Arbre des modules
Des dossiers:
- example.rs (root of our modules tree, generally named lib.rs or main.rs when using Cargo)
- first.rs
- second/
- mod.rs
- sub.rs
Modules:
- example -> example
- first -> example::first
- second -> example::second
- sub -> example::second::sub
- third -> example::third
example.rs
pub mod first;
pub mod second;
pub mod third {
...
}
Le module second
doit être déclaré dans le fichier example.rs
comme son parent est un example
et non, par exemple, d' first
et ne peut donc pas être déclaré dans le first.rs
fichier ou un autre fichier au même niveau de répertoire
second/mod.rs
pub mod sub;
L'attribut # [chemin]
L'attribut #[path]
Rust peut être utilisé pour spécifier le chemin pour rechercher un module particulier s'il ne se trouve pas dans l'emplacement standard. Cela est généralement déconseillé , car cela rend la hiérarchie des modules fragile et facilite la décomposition de la construction en déplaçant un fichier dans un répertoire complètement différent.
#[path="../path/to/module.rs"]
mod module;
Noms dans le code vs noms dans `use`
La syntaxe à deux points des noms dans l'instruction use
ressemble aux noms utilisés ailleurs dans le code, mais la signification de ces chemins est différente.
Les noms dans l'instruction use
par défaut sont interprétés comme absolus, en commençant à la racine de la caisse. Les noms ailleurs dans le code sont relatifs au module actuel.
La déclaration:
use std::fs::File;
a la même signification dans le fichier principal de la caisse ainsi que dans les modules. D'un autre côté, un nom de fonction tel que std::fs::File::open()
fera référence à la bibliothèque standard de Rust uniquement dans le fichier principal de la caisse, car les noms du code sont interprétés par rapport au module actuel.
fn main() {
std::fs::File::open("example"); // OK
}
mod my_module {
fn my_fn() {
// Error! It means my_module::std::fs::File::open()
std::fs::File::open("example");
// OK. `::` prefix makes it absolute
::std::fs::File::open("example");
// OK. `super::` reaches out to the parent module, where `std` is present
super::std::fs::File::open("example");
}
}
Pour que les noms std::…
se comportent partout comme dans la racine du coffre, vous pouvez ajouter:
use std;
Inversement, vous pouvez use
chemins relatifs en les préfixant avec self
mots super
clés self
ou super
:
use self::my_module::my_fn;
Accéder au module parent
Parfois, il peut être utile d'importer relativement des fonctions et des structures sans avoir à use
quelque chose avec son chemin absolu dans votre projet. Pour ce faire, vous pouvez utiliser le module super
, comme ceci:
fn x() -> u8 {
5
}
mod example {
use super::x;
fn foo() {
println!("{}", x());
}
}
Vous pouvez utiliser plusieurs fois super
pour atteindre le «grand-parent» de votre module actuel, mais vous devriez vous méfier des problèmes de lisibilité si vous utilisez super
trop de fois dans une importation.
Exportations et Visibilité
Structure du répertoire:
yourproject/
Cargo.lock
Cargo.toml
src/
main.rs
writer.rs
main.rs
// This is import from writer.rs
mod writer;
fn main() {
// Call of imported write() function.
writer::write()
// BAD
writer::open_file()
}
writer.rs
// This function WILL be exported.
pub fn write() {}
// This will NOT be exported.
fn open_file() {}
Organisation du code de base
Voyons comment nous pouvons organiser le code lorsque le code devient plus grand.
01. Fonctions
fn main() { greet(); } fn greet() { println!("Hello, world!"); }
02. Modules - Dans le même fichier
fn main() { greet::hello(); } mod greet { // By default, everything inside a module is private pub fn hello() { // So function has to be public to access from outside println!("Hello, world!"); } }
03. Modules - Dans un fichier différent du même répertoire
Lorsque vous déplacez du code dans un nouveau fichier, vous n'avez pas besoin d'encapsuler le code dans une déclaration de mod
. Le fichier lui-même agit comme un module.
// ↳ main.rs mod greet; // import greet module fn main() { greet::hello(); }
// ↳ greet.rs pub fn hello() { // function has to be public to access from outside println!("Hello, world!"); }
Lorsque vous déplacez du code dans un nouveau fichier, si ce code a été encapsulé dans une déclaration de
mod
, ce sera un sous-module du fichier.
// ↳ main.rs mod greet; fn main() { greet::hello::greet(); }
// ↳ greet.rs pub mod hello { // module has to be public to access from outside pub fn greet() { // function has to be public to access from outside println!("Hello, world!"); } }
04. Modules - Dans un fichier différent dans un répertoire différent
Lorsque vous déplacez du code dans un nouveau fichier dans un répertoire différent, le répertoire lui-même agit comme un module. Et mod.rs
dans la racine du module est le point d'entrée du module de répertoire. Tous les autres fichiers de ce répertoire agissent comme un sous-module de ce répertoire.
// ↳ main.rs mod greet; fn main() { greet::hello(); }
// ↳ greet/mod.rs pub fn hello() { println!("Hello, world!"); }
Lorsque vous avez plusieurs fichiers dans la racine du module,
// ↳ main.rs mod greet; fn main() { greet::hello_greet() }
// ↳ greet/mod.rs mod hello; pub fn hello_greet() { hello::greet() }
// ↳ greet/hello.rs pub fn greet() { println!("Hello, world!"); }
05. Modules - Avec self
fn main() { greet::call_hello(); } mod greet { pub fn call_hello() { self::hello(); } fn hello() { println!("Hello, world!"); } }
06. Modules - Avec super
- Lorsque vous souhaitez accéder à une fonction racine depuis un module,
fn main() { dash::call_hello(); } fn hello() { println!("Hello, world!"); } mod dash { pub fn call_hello() { super::hello(); } }
- Lorsque vous souhaitez accéder à une fonction dans le module externe / parent depuis un module imbriqué,
fn main() { outer::inner::call_hello(); } mod outer { pub fn hello() { println!("Hello, world!"); } mod inner { pub fn call_hello() { super::hello(); } } }
07. Modules - À l' use
- Lorsque vous souhaitez lier le chemin d'accès complet à un nouveau nom,
use greet::hello::greet as greet_hello; fn main() { greet_hello(); } mod greet { pub mod hello { pub fn greet() { println!("Hello, world!"); } } }
- Lorsque vous souhaitez utiliser le contenu de niveau de portée de la caisse
fn main() { user::hello(); } mod greet { pub mod hello { pub fn greet() { println!("Hello, world!"); } } } mod user { use greet::hello::greet as call_hello; pub fn hello() { call_hello(); } }