Rust importations de base (comprend)

Je ne trouve vraiment pas comment inclure (ou importer, injecter ou smth.) fonction d'un fichier (module) à l'autre.

Voici l'exemple.

Je commence un nouveau projet avec

cd ~/projects
cargo new proj --bin
cd proj
tree
# output
.
|
-- Cargo.toml
-- src
   |
   -- main.rs

Ensuite, je modifie main.rs et crée un nouveau fichier a.rs (dans le répertoire src) avec le code suivant:

// main.rs
fn main() { println!("{}", a::foo()); }


// a.rs
pub fn foo() -> int { 42i }

Je lance le projet avec cargo run

Ici, j'ai deux erreurs:

  • src / main. rs: 2:20: 2: 26 erreur: Impossible de résoudre. Utilisation du module non déclaré a
  • src / main. rs: 2:20: 2: 26 erreur: nom non résolu a::foo.

Pour l'instant, cela semble assez évident, j'ai juste besoin d'importer le a d'une manière ou d'une autre.

J'ai essayé d'ajouter les choses suivantes en première ligne à main.rs

  • use a; - > erreur: importation non résolue (peut-être que vous vouliez dire a::*?)
  • use a::*; - > erreur: les instructions d'importation glob sont expérimentales et peut-être boguées
  • use a::foo; - > erreur: importation non résolue a::foo. Peut-être un manque extern crate a?
  • extern crate a; use a::foo; - > erreur: Impossible de trouver la caisse pour a
  • extern crate proj; use proj::a::foo; - > Erreur: Impossible de trouver la caisse pour proj

J'ai lu le guide à la rouille-lang mais ne peut toujours pas comprendre comment faire des importations.

29
demandé sur Cœur 2014-10-07 01:11:37

2 réponses

Dans un mainish (module principal.rs, lib.rs, ou subdir/mod.rs), vous devez écrire mod a; pour tous les autres modules que vous souhaitez utiliser dans votre projet (ou dans le sous répertoire).

Dans n'importe quel autre module, vous devez écrire use a; ou use a::foo;

Vous êtes loin d'être la seule personne à être confondue par cela, et il est certainement possible de faire mieux, mais toute modification du système de module sera rejetée comme "trop confuse".

28
répondu o11c 2014-10-06 21:19:34

Dans Rust, il y a quelques mots-clés pour traiter les modules:

extern crate comble l'écart entre la cargaison et la rouille. Nous écrivons du code dans un fichier. rs, ce fichier peut être compilé avec rustc. Cargo va gérer les dépendances externes et appeler rustc. La ligne extern crate ... indique au compilateur de rechercher cet espace de noms, donc il est sans ambiguïté.

mod a deux usages:

  • lorsqu'il est utilisé avec des accolades il déclare un module (espace de noms).
  • lorsqu'il est utilisé avec juste un nom, il va chercher pour le module dans le système de fichiers local.

Les Modules peuvent être:

  • fichiers avec extension. rs
  • dossiers avec un fichier appelé mod.rs

use importe un espace de noms. Nous sommes tenus d'annoncer ce que nous allons utiliser avant de l'utiliser. La clause use est assez stricte, si nous indiquons use module1::moduleA; aucun autre module de module1 ne sera disponible mais moduleA. Un astérisque (*) peut être utilisé pour tout utiliser dans un module: use module1::*;. Les ensembles peuvent être utilisés aussi bien: use module1::{moduleA, moduleB};

Un exemple:

| main.rs
|- module1
      |- mod.rs
      |- moduleA.rs
      |- moduleB.rs

Mod.rs contient:

pub mod moduleA; // declare a sibling file
pub mod moduleA; // declare a sibling file

Main.rs contient:

///  ======
// use what Cargo downloaded
extern crate that_one_thing_i_need;

///  ======

// add my other sources to the tree:
mod module1;

// some local stuff
mod local {
    pub fn my_function() {}
}

//   ======

// make the symbols locally available:
use module1::moduleA::*;
use module1::moduleB::{functionX, moduleY, typeZ};

// we still need to announce what stuff from the external crate
// we want to use:
// We can do local aliases that will be valid in this one file.
use that_one_thing_i_need::fancy_stuff as fs;

///  ======

fn main() {
    // we can use anything here from the namespaces we are using:
    //      moduleA
    //      functionX
    //      moduleY
    //      typeZ
    //      fs

    // We can access stuff by navigating from the outermost visible
    // module name
    local::my_function();
}
Les symboles

Ne sont utilisables qu'à partir du module. Si vous voulez franchir cette barrière (même sur un module déclaré localement), nous devons les rendre publics en utilisant le mot clé pub.

7
répondu Luis Ayuso 2017-06-07 14:27:44