Suche…


Syntax

  • Modname ; // Suchen Sie das Modul in modname .rs oder modname /mod.rs im gleichen Verzeichnis
  • mod modname { block }

Modulbaum

Dateien:

- example.rs (root of our modules tree, generally named lib.rs or main.rs when using Cargo)
- first.rs
- second/
  - mod.rs
  - sub.rs

Module:

- 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 {
    ...
}

Das second Modul muss in der Datei example.rs deklariert werden. Das first.rs ist example und nicht z. B. first und kann daher nicht in der Datei first.rs oder einer anderen Datei in derselben Verzeichnisebene deklariert werden

second/mod.rs

pub mod sub;

Das # [Pfad] -Attribut

Das #[path] -Attribut von Rust kann verwendet werden, um den Pfad für die Suche nach einem bestimmten Modul anzugeben, wenn es sich nicht an der Standardposition befindet. Dies wird jedoch in der Regel nicht empfohlen , da die Modulhierarchie dadurch brüchig wird und der Build leicht durch Verschieben einer Datei in ein völlig anderes Verzeichnis unterbrochen werden kann.

#[path="../path/to/module.rs"]
mod module;

Namen im Code vs. Namen in "use"

Die Doppelpunkt-Syntax der Namen in der use Anweisung sieht ähnlich aus wie die Namen, die an anderer Stelle im Code verwendet werden. Die Bedeutung dieser Pfade ist jedoch unterschiedlich.

Namen in der use Anweisung werden standardmäßig als absolut interpretiert, beginnend am Kistenstamm. Namen an anderer Stelle im Code sind relativ zum aktuellen Modul.

Die Aussage:

use std::fs::File;

hat die gleiche Bedeutung in der Hauptdatei der Kiste sowie in Modulen. Ein Funktionsname wie std::fs::File::open() verweist dagegen nur in der Hauptdatei der Kiste auf die Standardbibliothek von Rust, da die Namen im Code relativ zum aktuellen Modul interpretiert werden.

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"); 
   } 
}

Damit sich std::… Namen überall gleich verhalten wie im Stamm der Kiste, könnten Sie Folgendes hinzufügen:

use std;

Umgekehrt können Sie machen use Pfade relativ indem man sie mit prefixing self oder super - Schlüsselwörter:

 use self::my_module::my_fn;

Zugriff auf das übergeordnete Modul

Manchmal kann es nützlich sein , um Importfunktionen und Strukturen relativ ohne zu haben , use etwas mit seinem absoluten Pfad in Ihrem Projekt. Um dies zu erreichen, können Sie das Modul verwenden super , etwa so:

fn x() -> u8 {
    5
}

mod example {
    use super::x;

    fn foo() {
        println!("{}", x());
    }
}

Sie können super mehrfach verwenden, um die "Großeltern" Ihres aktuellen Moduls zu erreichen. Sie sollten jedoch Bedenken hinsichtlich Lesbarkeitsproblemen haben, wenn Sie in einem Import zu oft super .

Exporte und Sichtbarkeit

Verzeichnisaufbau:

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-Organisation

Mal sehen, wie wir den Code organisieren können, wenn die Codebase größer wird.

01. Funktionen

fn main() {
  greet();
}

fn greet() {
  println!("Hello, world!");
}

02. Module - In derselben Datei

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. Module - In einer anderen Datei im selben Verzeichnis

Wenn Sie Code in eine neue Datei verschieben, müssen Sie den Code nicht in eine mod Deklaration mod . Die Datei selbst fungiert als 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!");
}

Wenn ein Code in eine neue Datei verschoben wird und dieser Code aus einer mod Deklaration eingeschlossen wurde, ist dies ein Untermodul der Datei.

// ↳ 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. Module - In einer anderen Datei in einem anderen Verzeichnis

Wenn Sie Code in eine neue Datei in einem anderen Verzeichnis verschieben, fungiert das Verzeichnis selbst als Modul. Und mod.rs im Modulstamm ist der Einstiegspunkt in das Verzeichnismodul. Alle anderen Dateien in diesem Verzeichnis fungieren als Untermodul dieses Verzeichnisses.

// ↳ main.rs
mod greet;

fn main() {
  greet::hello();
}
// ↳ greet/mod.rs
pub fn hello() {
  println!("Hello, world!");
}

Wenn Sie mehrere Dateien im Modulstamm haben,

// ↳ 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. Module - Mit sich self

fn main() {
  greet::call_hello();
}

mod greet {
  pub fn call_hello() { 
    self::hello();
  }

  fn hello() {
    println!("Hello, world!");
  }
}

06. Module - Mit super

  1. Wenn Sie innerhalb eines Moduls auf eine Root-Funktion zugreifen möchten,
fn main() {
  dash::call_hello();
}

fn hello() {
  println!("Hello, world!");
}

mod dash {
  pub fn call_hello() {
    super::hello();
  }
}
  1. Wenn Sie innerhalb eines verschachtelten Moduls auf eine Funktion im äußeren / übergeordneten Modul zugreifen möchten,
fn main() {
  outer::inner::call_hello();
}

mod outer {

  pub fn hello() {
    println!("Hello, world!");
  }

  mod inner {
    pub fn call_hello() {
      super::hello();
    }
  }

}

07. Module - Mit use

  1. Wenn Sie den vollständigen Pfad an einen neuen Namen binden möchten,
use greet::hello::greet as greet_hello;

fn main() {
  greet_hello();
}

mod greet {
  pub mod hello {
    pub fn greet() {
      println!("Hello, world!");
    }
  }
}
  1. Wenn Sie Inhalt der Kistenumfangsebene verwenden möchten
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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow