Rust Use Imports
The use keyword is a shortcut that brings a long path into a scope under a short name. The long path is written once in the use line.
The long path, written again and again
Without use, every mention writes the full path:
fn main() {
let mut stock = std::collections::HashMap::new();
stock.insert("apple", 3);
println!("apple = {}", stock["apple"]);
}Bring a name in once, use it short
Use use path; to bring a name into this scope: from then on, the short name works here. For structs, enums and other items, the habit is to import the full path, like HashMap here:
use std::collections::HashMap;
let mut stock = HashMap::new();
stock.insert("apple", 3);
println!("apple = {}", stock["apple"]);For functions, import the parent module
For functions, the habit is the opposite. Import the parent module and call shop::price(). The call still shows where the function lives:
mod shop {
pub fn price(item: &str) -> i32 { if item == "apple" { 3 } else { 5 } }
}
use crate::shop;
println!("apple = {} coins", shop::price("apple"));Two items, one name: rename one
Two items can share a name — fmt::Result and io::Result are the famous pair. Keep their parents in the path, or rename one with as:
use std::fmt::Result as FmtResult;
fn ready() -> FmtResult { Ok(()) }
println!("ready = {:?}", ready());Nested paths import neighbours in one line
Braces group imports that share a path. And self in a nested list means the parent itself, as in std::io::{self, Write}:
use std::{collections::HashMap, io};
use std::io::{self, Write};The glob imports everything public
Use the glob * to import everything public in a path. It is handy in tests. But it hides where names came from, so use it with care:
use std::collections::*;
let mut set = HashSet::new();
set.insert("rust");
println!("has rust = {}", set.contains("rust"));pub use puts a deep item on the front door
Use pub use at the crate root to re-export a deep item at a short path. Users write use art::PrimaryColor instead of the long internal path. Your inside layout stays free to differ from your public layout:
mod art {
pub mod colors {
#[derive(Debug)]
pub struct PrimaryColor;
}
pub use crate::art::colors::PrimaryColor;
}
use crate::art::PrimaryColor;
println!("{:?}", PrimaryColor);Example
mod shop {
pub fn price(item: &str) -> i32 { if item == "apple" { 3 } else { 5 } }
}
use std::{collections::HashMap, fmt::Result as FmtResult};
fn ready() -> FmtResult { Ok(()) }
fn main() {
use crate::shop;
ready().expect("ready");
let mut stock = HashMap::new();
stock.insert("apple", shop::price("apple"));
println!("apple = {} coins", stock["apple"]);
}Key points
- A use line trades one long path for a short name inside one scope.
- A use shortcut works only in the scope where you wrote it.
- A child module needs its own use.
- Or it can use super:: to reach the parent's shortcut.
- Paths from another crate start with the crate name.
- std needs no Cargo.toml entry.
- But a crate like rand must be listed under [dependencies] first.
- A shortcut to a private item is still refused — use is about shorter writing, not open doors.
In this example, the use lines do three jobs. Inside main, a use line imports the parent module shop. So the call keeps its address: shop::price("apple") returns 3. And that shortcut exists only inside main, the scope where it is written. The nested top line imports two neighbours at once. It brings in HashMap in full, as structs are imported. It also brings in the fmt Result under the new name FmtResult. So it can never clash with another Result. ready() returns that FmtResult and expect confirms it is Ok. The map stores the apple price, and the println! reads it back: apple = 3 coins.
Note
use never changes privacy.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
Two types are both called Result. How can you use both in one scope?