use

Let's see the main usages of use keyword.

01. Bind a full path to a new name

Mainly use keyword is used to bind a full path of an element to a new name. So user doesn’t want to repeat the full path each time.

// -- Initial code without use keyword --
mod phrases { 
  pub mod greetings { 
    pub fn hello() { 
      println!("Hello, world!");
    }
  }
}

fn main() { 
  phrases::greetings::hello(); // using full path
}


// -- Usage of use keyword --
// 01. create alias for module
use phrases::greetings;
fn main() { 
  greetings::hello();
}

// 02. create alias for module elements
use phrases::greetings::hello;
fn main() { 
  hello();
}

// 03. customize names with as keyword
use phrases::greetings::hello as greet;
fn main() { 
  greet();
}

02. Import elements to scope

Another common usage of use is importing elements to scope. Remember that, this is also bit similar to creating alias and using it instead of using the full path.

fn hello() -> String {
  "Hello, world!".to_string()
}

#[cfg(test)]
mod tests {
  use super::hello; //import hello() into scope

  #[test]
  fn test_hello() {
    assert_eq!("Hello, world!", hello()); //if not using above use statement, we can run same via super::hello()
  }
}

💡 By default, use declarations use absolute paths, starting from the crate root. But self and super declarations make that path relative to the current module.

Same way use keyword is used to import the elements of other crates including std , Rust’s Standard Library.

// -- 01. importing elements --
use std::fs::File;

fn main() {
    File::create("empty.txt").expect("Can not create the file!");
}


// -- 02. importing module and elements--
std::fs::{self, File} //use std::fs; use std::fs::File;

fn main() {
    fs::create_dir("some_dir").expect("Can not create the directry!");
    File::create("some_dir/empty.txt").expect("Can not create the file!");
}


// -- 03. importing multiple elements
use std::fs::File;
use std::io::{BufReader, BufRead}; //use std::io::BufReader; use std::io::BufRead;

fn main() {
    let file = File::open("src/hello.txt").expect("file not found");
    let buf_reader = BufReader::new(file);

    for line in buf_reader.lines() {
        println!("{}", line.unwrap());
    }
}

We don’t need to use extern crate std; when using std library. We will discuss more about this under Standard Library section.

💡 use statements import only what we’ve specified into the scope, instead of importing all elements of a module or crate. So it improves the efficiency of the program.

03. Re-exporting

Another special case is pub use. When creating a module, you can export things from another module into your module. So after that they can be accessed directly from your module. This is called re-exporting.

// ↳ main.rs
mod phrases;

fn main() {
    phrases::hello(); //not directly map
}

// ↳ phrases/mod.rs
pub mod greetings;

pub use self::greetings::hello; //re-export greetings::hello to phrases

// ↳ phrases/greetings.rs
pub fn hello() {
  println!("Hello, world!");
}

This pattern is quite common in large libraries. It helps to hide the complexity of the internal module structure of the library from users, because users don’t need to know/follow whole directory map of the elements of the library while working with them.

Last updated