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

  1. 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();
  }
}
  1. 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

  1. 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!");
    }
  }
}
  1. 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();
  }
}


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow