Modules

Modules allow you to structure code in a maintainable way, so you don't end up with everything in one giant file. They also let you hide details so that consumers of your code don't rely on internal implementation details.

Creating modules

You declare modules with the mod keyword, and then you can include them from one of three places:

  • Directly with a block delimited by curly braces
  • In a file at the same level with the name of the module
  • Inside a folder with the module name, in the file mod.rs

Modules can also be either public (pub mod) or private (mod). If they're public, anyone consuming your crate can use the module and its pub members. Otherwise, private members are accessible only to themselves and their descendants.

Let's say you're creating a module called math. Then inside your current module (starting from main.rs or lib.rs, unless you're nested inside another module already) you would create this module. Let's assume you're working in main.rs for the sake of these examples, but it's the same either way.

#![allow(unused)]
fn main() {
// in main.rs
pub mod math {
    // look, I didn't say this was a *useful* module
    pub fn add(x: u32, y: u32) -> u32 {
        x + y
    }
}
}

If you want to break it out into other files, you can do that. You still declare the module in main.rs or your other file:

#![allow(unused)]
fn main() {
pub mod math;
}

And then you put the contents in either math.rs or math/mod.rs, depending on your preference. Usually it's clearer to use the math.rs style over math/mod.rs, because otherwise your editor can be filled with a lot of mod.rs files and it's not clear which one you're working on!

#![allow(unused)]
fn main() {
pub fn add(x: u32, y: u32) -> u32 {
    x + y
}
}

And that's all there is to creating modules!

Using modules

To use what's declared in another module, you use the use keyword. This brings things into scope. (If you want to re-export them, you can pub use them.)

#![allow(unused)]
fn main() {
use std::collections::HashMap;
}

If you refer to super::thing, that gets thing from the parent module.

If you refer to crate::thing, that gets thing from the root of the crate you're in.