Recherche…


Syntaxe

  • mod modname ; // Recherche le module dans modname .rs ou modname /mod.rs dans le même répertoire
  • mod modname { block }

Arbre des modules

Des dossiers:

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

Le module second doit être déclaré dans le fichier example.rs comme son parent est un example et non, par exemple, d' first et ne peut donc pas être déclaré dans le first.rs fichier ou un autre fichier au même niveau de répertoire

second/mod.rs

pub mod sub;

L'attribut # [chemin]

L'attribut #[path] Rust peut être utilisé pour spécifier le chemin pour rechercher un module particulier s'il ne se trouve pas dans l'emplacement standard. Cela est généralement déconseillé , car cela rend la hiérarchie des modules fragile et facilite la décomposition de la construction en déplaçant un fichier dans un répertoire complètement différent.

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

Noms dans le code vs noms dans `use`

La syntaxe à deux points des noms dans l'instruction use ressemble aux noms utilisés ailleurs dans le code, mais la signification de ces chemins est différente.

Les noms dans l'instruction use par défaut sont interprétés comme absolus, en commençant à la racine de la caisse. Les noms ailleurs dans le code sont relatifs au module actuel.

La déclaration:

use std::fs::File;

a la même signification dans le fichier principal de la caisse ainsi que dans les modules. D'un autre côté, un nom de fonction tel que std::fs::File::open() fera référence à la bibliothèque standard de Rust uniquement dans le fichier principal de la caisse, car les noms du code sont interprétés par rapport au module actuel.

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

Pour que les noms std::… se comportent partout comme dans la racine du coffre, vous pouvez ajouter:

use std;

Inversement, vous pouvez use chemins relatifs en les préfixant avec self mots super clés self ou super :

 use self::my_module::my_fn;

Accéder au module parent

Parfois, il peut être utile d'importer relativement des fonctions et des structures sans avoir à use quelque chose avec son chemin absolu dans votre projet. Pour ce faire, vous pouvez utiliser le module super , comme ceci:

fn x() -> u8 {
    5
}

mod example {
    use super::x;

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

Vous pouvez utiliser plusieurs fois super pour atteindre le «grand-parent» de votre module actuel, mais vous devriez vous méfier des problèmes de lisibilité si vous utilisez super trop de fois dans une importation.

Exportations et Visibilité

Structure du répertoire:

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() {}

Organisation du code de base

Voyons comment nous pouvons organiser le code lorsque le code devient plus grand.

01. Fonctions

fn main() {
  greet();
}

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

02. Modules - Dans le même fichier

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 - Dans un fichier différent du même répertoire

Lorsque vous déplacez du code dans un nouveau fichier, vous n'avez pas besoin d'encapsuler le code dans une déclaration de mod . Le fichier lui-même agit comme un 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!");
}

Lorsque vous déplacez du code dans un nouveau fichier, si ce code a été encapsulé dans une déclaration de mod , ce sera un sous-module du fichier.

// ↳ 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 - Dans un fichier différent dans un répertoire différent

Lorsque vous déplacez du code dans un nouveau fichier dans un répertoire différent, le répertoire lui-même agit comme un module. Et mod.rs dans la racine du module est le point d'entrée du module de répertoire. Tous les autres fichiers de ce répertoire agissent comme un sous-module de ce répertoire.

// ↳ main.rs
mod greet;

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

Lorsque vous avez plusieurs fichiers dans la racine du module,

// ↳ 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 - Avec self

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

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

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

06. Modules - Avec super

  1. Lorsque vous souhaitez accéder à une fonction racine depuis un module,
fn main() {
  dash::call_hello();
}

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

mod dash {
  pub fn call_hello() {
    super::hello();
  }
}
  1. Lorsque vous souhaitez accéder à une fonction dans le module externe / parent depuis un module imbriqué,
fn main() {
  outer::inner::call_hello();
}

mod outer {

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

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

}

07. Modules - À l' use

  1. Lorsque vous souhaitez lier le chemin d'accès complet à un nouveau nom,
use greet::hello::greet as greet_hello;

fn main() {
  greet_hello();
}

mod greet {
  pub mod hello {
    pub fn greet() {
      println!("Hello, world!");
    }
  }
}
  1. Lorsque vous souhaitez utiliser le contenu de niveau de portée de la caisse
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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow