How do I do a basic import/include of a function from one module to another in Rust 2015?

In a mainish module (main.rs, lib.rs, or subdir/mod.rs), you need to write mod a; for all other modules that you want to use in your whole project (or in the subdir).

In any other module, you need to write use a; or use a::foo;

You're far from the only person to be confused by this, and it's certainly possible to do better, but any changes to the module system will get rejected as "too confusing".

Edit: this answer was written for the "Rust 2015" language standard. Changes were made for the "Rust 2018" standard, see this blog post and the edition guide


In Rust, there are some keywords to deal with modules:

extern crate

extern crate fills the gap between Cargo and Rust. We write code in a .rs file, this file can be compiled with rustc. Cargo will manage external dependencies and call rustc. The extern crate ... line tells the compiler to look for this namespace, so it is unambiguous.

Editor's noteextern crate is not required in many cases if you are using the Rust 2018 edition.

mod

mod has two uses:

  • when used with curly braces it declares a module (namespace).
  • when used with just a name, it will look for the module in the local filesystem.

Modules can be:

  • files with extension .rs
  • folders with one file called mod.rs

use

use imports a namespace. We are required to announce what are we going to use before using it. The use clause is pretty strict, if we state use module1::moduleA; no other module from module1 will be available but moduleA. An asterisk (*) can be used to use everything within a module: use module1::*;. Sets can be used as well: use module1::{moduleA, moduleB};

An example:

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

mod.rs contains:

pub mod moduleA; // declare a child module
pub mod moduleB; // declare a child module

main.rs contains:

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

///  ======

mod module1; // declare a child module

// some local stuff I want to scope
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();
}

Symbols are only usable from within the module. If you want to cross this barrier (even on a locally declared module) we need to make them public using the keyword pub.

Tags:

Module

Rust