Rust lang series episode #16 — modules (#rust-series)

in #rust-series8 years ago (edited)

Hello everyone, new episode of rust-series is here, today we will discuss modules. Up to now we always put our code into one .rs file and it is fine for our limited needs, indeed. But in general, when you work on something it's not practical at all. It's necessary to categorize things into multiple files and modules to have concerns separated. There things to remember:

  • Module is declared with mod
  • Public function in module is declared with using pub
  • track to module path is done by reference by ::

See function in module and its calling from main function:

mod my {
  pub fn public_module_function() {
    private_module_function();
  }

  fn private_function() {
    println!("private module function called");
  }
}


fn main() {    
  my::public_module_function();
}

use

If we use some module function multiple times, it's worth to alias it with use to bind path to a new name.

fn main() {
  use my::public_module_function;

  public_module_function();
  public_module_function();
  public_module_function();

}

Nested modules

We can nest modules as we want

mod my {
  mod math {
    pub fn calculate() {
      println("calculated");
    }
  }
  mod graphics {
    pub fn draw_box() {
      println!("box drawn");
    }
  }
}

fn main() {

  my::math::calculate();
  my::graphics::drawbox();
}

Super and self

Sometime we need to remove ambiguity, super and self are useful for this. Check this piece of code:

fn common_name_function() {
    println!("common_name_function outside module");
}

mod my {
    fn common_name_function() {
        println!("common_name_function in module");
    }
    mod math {
        pub fn calculate() {
            println!("calculating...");
        }
    }

    mod graphics {
        pub fn draw() {
            println!("drawing...");
        }
    }

    pub fn calculate_and_draw() {
        common_name_function();
        super::common_name_function();
        self::math::calculate();
        self::graphics::draw();
    }
}

fn main() {
    my::calculate_and_draw();
}

# output
common_name_function in module
common_name_function outside module
calculating...
drawing...

Multiple files

It's also useful to split modules into multiple files.

Assume we have two files - main.rs and my.rs. Main.rs will contain main function and my.rs my module.

my.rs

We just define function but don't forget pub keyword to make sure function will be publicly accessible.

pub fn my_mod_function() {
  println!("my_mod_function called!");
}

main.rs

Here we just need to say we will use my mod with mod keyword.

mod my;

fn main() {
  my::my_mod_function();
}

# output
my_mod_function called!

Note that "mod my" makes Rust searching for my.rs file or my/mod.rs file.

Public modes

We ca also refer additional modules like with pub mod. Check the example

my/mod.rs

pub mod additional;

my/additional.rs

pub fn additional_mod_function() {
    println!("additional_mod_function called!")
}

main.rs

fn main() {
  my::additional::additional_mod_function();
}

# output
additional_mod_function called!

With these principle you can create as complex module structures as you wish.

That's all for today, thank you for your appreciations, feel free to comment and point out possible mistakes (first 24 hours works the best but any time is fine). Jesus bless your programming skills, use them wisely and see you next time.

Meanwhile you can also check official documentation to find more about discussed crates and modules:

#rust-series
#rust-lang
#rust

Coin Marketplace

STEEM 0.15
TRX 0.15
JST 0.028
BTC 53778.84
ETH 2224.93
USDT 1.00
SBD 2.30