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

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

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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow