Sök…
Syntax
- mod modnamn ; // Sök efter modulen i modname .rs eller modname / mod.rs i samma katalog
- mod modname { block }
Moduler träd
filer:
- example.rs (root of our modules tree, generally named lib.rs or main.rs when using Cargo)
- first.rs
- second/
- mod.rs
- sub.rs
moduler:
- 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 {
...
}
Modulen second
måste deklareras i filen example.rs
som dess överordnade är example
och inte till exempel first
och kan därför inte deklareras i first.rs
eller en annan fil på samma katalognivå
second/mod.rs
pub mod sub;
Attributet # [sökväg]
Rusts attribut #[path]
kan användas för att specificera sökvägen att söka efter en viss modul om den inte finns på standardplatsen. Detta är dock vanligtvis avskräckt eftersom det gör modulhierarkin ömtålig och gör det enkelt att bryta byggandet genom att flytta en fil i en helt annan katalog.
#[path="../path/to/module.rs"]
mod module;
Namn i kod kontra namn i `användning`
Syntaxen med namn i dubbel kolon i use
liknar namnen som används någon annanstans i koden, men betydelsen av dessa banor är annorlunda.
Namn i use
tolkas som standard som absoluta, börjar vid lådroten. Namnen någon annanstans i koden är relativt den aktuella modulen.
Påståendet:
use std::fs::File;
har samma betydelse i lådans huvudfil och i moduler. Å andra sidan hänvisar ett funktionsnamn som std::fs::File::open()
till Rusts standardbibliotek endast i lådans huvudfil, eftersom namn i koden tolkas relativt den aktuella modulen.
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");
}
}
För att göra std::…
namn bete sig överallt på samma sätt som i rotlådan du kan lägga till:
use std;
Omvänt kan du use
vägar förhållande genom att inleda dem med self
eller super
sökord:
use self::my_module::my_fn;
Åtkomst till överordnade modulen
Ibland kan det vara användbart att importera funktioner och strukturer relativt utan att behöva use
något med sin absoluta sökväg i ditt projekt. För att uppnå detta kan du använda modulen super
, så:
fn x() -> u8 {
5
}
mod example {
use super::x;
fn foo() {
println!("{}", x());
}
}
Du kan använda super
flera gånger för att nå "farföräldrar" i din nuvarande modul, men du bör vara försiktig med att införa läsbarhetsfrågor om du använder super
för många gånger i en import.
Export och synlighet
Katalogstruktur:
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() {}
Grundläggande kodorganisation
Låt oss se hur vi kan ordna koden när kodbasen blir större.
01. Funktioner
fn main() { greet(); } fn greet() { println!("Hello, world!"); }
02. Moduler - I samma fil
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. Moduler - I en annan fil i samma katalog
När du flyttar en kod till en ny fil behöver du inte pakera in koden i en mod
. Filen fungerar själv som en modul.
// ↳ 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!"); }
När du flyttar en kod till en ny fil, om den koden har lagts in från en
mod
, kommer det att vara en undermodul för filen.
// ↳ 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. Moduler - I en annan fil i en annan katalog
När du flyttar en kod till en ny fil i en annan katalog fungerar katalogen själv som en modul. Och mod.rs
i mod.rs
är ingångspunkten till katalogmodulen. Alla andra filer i den katalogen fungerar som en undermodul i den katalogen.
// ↳ main.rs mod greet; fn main() { greet::hello(); }
// ↳ greet/mod.rs pub fn hello() { println!("Hello, world!"); }
När du har flera filer i modulroten,
// ↳ 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. Moduler - Med self
fn main() { greet::call_hello(); } mod greet { pub fn call_hello() { self::hello(); } fn hello() { println!("Hello, world!"); } }
06. Moduler - Med super
- När du vill komma åt en rotfunktion inifrån en modul,
fn main() { dash::call_hello(); } fn hello() { println!("Hello, world!"); } mod dash { pub fn call_hello() { super::hello(); } }
- När du vill komma åt en funktion i yttre / överordnade modulen från en kapslad modul,
fn main() { outer::inner::call_hello(); } mod outer { pub fn hello() { println!("Hello, world!"); } mod inner { pub fn call_hello() { super::hello(); } } }
07. Moduler - Med use
- När du vill binda hela sökvägen till ett nytt namn,
use greet::hello::greet as greet_hello; fn main() { greet_hello(); } mod greet { pub mod hello { pub fn greet() { println!("Hello, world!"); } } }
- När du vill använda innehåll i lådans omfattningsnivå
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(); } }