Zoeken…
Syntaxis
- mod modnaam ; // Zoek naar de module in modnaam .rs of modnaam /mod.rs in dezelfde map
- mod modname { block }
Modulesboom
bestanden:
- 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 {
...
}
De second
module moet in het example.rs
bestand worden gedeclareerd, omdat de ouder ervan een example
en niet bijvoorbeeld als first
en dus niet kan worden gedeclareerd in het first.rs
of een ander bestand in hetzelfde first.rs
second/mod.rs
pub mod sub;
Het kenmerk # [pad]
Het kenmerk #[path]
Rust kan worden gebruikt om het pad op te geven voor het zoeken naar een bepaalde module als deze zich niet op de standaardlocatie bevindt. Dit wordt echter meestal afgeraden , omdat het de modulehiërarchie kwetsbaar maakt en het gemakkelijk maakt om de build te verbreken door een bestand naar een volledig andere map te verplaatsen.
#[path="../path/to/module.rs"]
mod module;
Namen in code versus namen in `gebruik`
De dubbele dubbele syntaxis van namen in de use
lijkt op namen die elders in de code worden gebruikt, maar de betekenis van deze paden is anders.
Namen in de use
worden standaard als absoluut geïnterpreteerd, beginnend bij de kratwortel. Namen elders in de code zijn relatief ten opzichte van de huidige module.
De verklaring:
use std::fs::File;
heeft dezelfde betekenis in het hoofdbestand van de krat als in modules. Aan de andere kant zal een functienaam zoals std::fs::File::open()
alleen naar de standaardbibliotheek van Rust verwijzen in het hoofdbestand van de krat, omdat namen in de code worden geïnterpreteerd ten opzichte van de huidige module.
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");
}
}
Om std::…
te maken gedragen de namen zich overal hetzelfde als in de root van de krat die je zou kunnen toevoegen:
use std;
Omgekeerd kunt u use
paden relatieve door ze te laten voorafgaan met self
of super
keywords:
use self::my_module::my_fn;
Toegang tot de bovenliggende module
Soms kan het handig zijn om functies en structuren relatief te importeren zonder iets met het absolute pad in uw project te hoeven use
. Om dit te bereiken, kunt u de module super
als volgt gebruiken:
fn x() -> u8 {
5
}
mod example {
use super::x;
fn foo() {
println!("{}", x());
}
}
Je kunt super
meerdere keren gebruiken om de 'grootouder' van je huidige module te bereiken, maar je moet oppassen met problemen met de leesbaarheid als je super
te vaak in één import gebruikt.
Export en zichtbaarheid
Directory structuur:
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() {}
Basiscode organisatie
Laten we eens kijken hoe we de code kunnen organiseren, wanneer de codebase groter wordt.
01. Functies
fn main() { greet(); } fn greet() { println!("Hello, world!"); }
02. Modules - In hetzelfde bestand
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 - In een ander bestand in dezelfde map
Wanneer u een code naar een nieuw bestand verplaatst, hoeft u de code niet in een mod
aangifte te verpakken. Bestand zelf fungeert als een 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!"); }
Wanneer een code naar een nieuw bestand wordt verplaatst, als die code uit een
mod
aangifte is gewikkeld, is dat een submodule van het bestand.
// ↳ 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 - In een ander bestand in een andere map
Wanneer een code naar een nieuw bestand in een andere map wordt verplaatst, fungeert de map zelf als een module. En mod.rs
in de module root is het toegangspunt tot de mod.rs
. Alle andere bestanden in die map fungeert als een submodule van die map.
// ↳ main.rs mod greet; fn main() { greet::hello(); }
// ↳ greet/mod.rs pub fn hello() { println!("Hello, world!"); }
Wanneer u meerdere bestanden in de modulewortel heeft,
// ↳ 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 - Met self
fn main() { greet::call_hello(); } mod greet { pub fn call_hello() { self::hello(); } fn hello() { println!("Hello, world!"); } }
06. Modules - Met super
- Wanneer u vanuit een module toegang wilt krijgen tot een rootfunctie,
fn main() { dash::call_hello(); } fn hello() { println!("Hello, world!"); } mod dash { pub fn call_hello() { super::hello(); } }
- Wanneer u vanuit een geneste module toegang wilt krijgen tot een functie in de buitenste / bovenliggende module,
fn main() { outer::inner::call_hello(); } mod outer { pub fn hello() { println!("Hello, world!"); } mod inner { pub fn call_hello() { super::hello(); } } }
07. Modules - Met use
- Wanneer u het volledige pad aan een nieuwe naam wilt binden,
use greet::hello::greet as greet_hello; fn main() { greet_hello(); } mod greet { pub mod hello { pub fn greet() { println!("Hello, world!"); } } }
- Wanneer u inhoud op kratbereik wilt gebruiken
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(); } }