| title | Use |
|---|---|
| slug | use |
- A
usestatement is used to bring items (types, functions, traits, modules, etc.) into the current scope.- It doesn't import anything; instead, it creates a local name (an alias) in the current scope.
- This allows us:
- to refer to items by shorter names instead of their full paths.
- to re-export items (by publicly exposing items from another module or crate using
pub use).
A use statement can start from:
- The current crate:
use crate::: Absolute path from the current crate.use super::: Relative path from the parent module.use self::: Relative path from the current module. Since Rust 2018, this is often optional.
- External crates:
use my_app::: The package name when having bothmain.rs/lib.rs(Cross-Crate). (my_appis the package name in the rootCargo.toml)use uuid::: Third-party crates. (uuidis a crate for UUID generation)
- Rust library crates:
use std::: Rust standard library.use core::: Rust core library. (contains functionality that does not require an operating system or a heap allocator)use alloc::: Rust core allocation and collections library. (Usually used in#![no_std]projects)
A use statement can select items from a path in different ways:
use path::item;: Bring a single item (type, function, trait, module, etc.) into scope.use path::{item_a, item_b};: Bring multiple specific items into scope.use path::*;: Bring all public items from a module into scope.use path::{self, item_a};: Bring both the module itself and specific items into scope.use path::nested::item;: Bring an item from a nested path into scope.use path::{nested::item, nested2::item};: Bring items from different nested modules under a shared base path in a single statement.use path::item as custom_name;oruse path::{self, item_a, item_b as custom_name};: Rename items when bringing them into scope.
- Re-exporting publicly exposes items from another module or crate using
pub use, allowing us to decouple the public API from internal module structure. - Re-exporting can be combined with visibility modifiers to control how far items are exposed within a crate.
pub use path::item;: Visible to anyone who can access the crate (fully public).pub(crate) use path::item;: Visible anywhere inside the current crate.pub(super) use path::item;: Visible only in the parent module.pub(in crate::path) use path::item;: Visible only within the specified module path inside the crate.
use inline::nested::greet;
use inline2::greet as greet2;
use inline2::nested::greet as greet3;
fn main() {
greet();
greet2();
greet3();
}
mod inline {
pub fn greet() {
println!("Inline");
}
pub mod nested {
pub fn greet() {
println!("Nested");
}
}
}
mod inline2 {
use crate::inline; // Bring `inline` into this module's scope.
pub fn greet() {
inline::greet();
}
pub mod nested {
pub use super::greet; // Re-export `inline2::greet` as `inline2::nested::greet`
}
}
// ⭐️ `use crate::inline;` can move directly inside `inline2::greet()` as well.[!lab]
cargo new my_app && cd my_app touch src/lib.rs src/foo.rs cargo add uuid -F v7
my_app
├── Cargo.toml (package name my_app)
└── src
├── main.rs
├── lib.rs
└── foo.rs{{< tabs count=3 label="Select File" >}} {{< tab label="foo.rs" >}}
use uuid::Uuid;
pub fn new_id() -> Uuid {
Uuid::now_v7()
}
#[cfg(test)]
mod tests {
use super::*;
use uuid::Version;
#[test]
fn test_new_id_is_version_7() {
let id = new_id();
assert_eq!(id.get_version(), Some(Version::SortRand));
}
}{{< /tab >}} {{< tab label="lib.rs" >}}
mod foo;
pub use foo::new_id;
pub struct Person {
pub name: String,
}
pub trait Greet {
const PREFIX: &'static str; // 💡 Required constant
fn greet(&self) -> String; // 💡 Required method
}
impl Greet for Person {
const PREFIX: &'static str = "Hello";
fn greet(&self) -> String {
format!("{} {}!", Self::PREFIX.to_owned(), self.name)
}
}{{< /tab >}} {{< tab label="main.rs" >}}
use my_app::{Greet, Person as Employer, new_id};
fn main() {
let steve = Employer { name: "Steve".to_string() };
let apple = Company { name: "Apple".to_string() };
println!("{}", steve.greet());
println!("{}", apple.greet());
print!("{}", new_id())
}
struct Company {
name: String,
}
impl Greet for Company {
const PREFIX: &'static str = "Welcome to";
fn greet(&self) -> String {
format!("{} {}!", Self::PREFIX.to_owned(), self.name)
}
}{{< /tab >}} {{< /tabs >}}
use std::fs::{self, File}; // Bringing the `fs` module and `fs::File` struct into scope
fn main() {
fs::create_dir("some_dir").expect("Failed to create the directory!");
File::create("some_dir/empty.txt").expect("Failed to create the file!");
}use core::cmp::Ordering; // Bring Ordering into scope
// Bring collections (HashMap, VecDeque), sleep, and Duration into scope
use std::{collections::{HashMap, VecDeque}, thread::sleep, time::Duration };
extern crate alloc; // Enable the alloc crate
use alloc::vec::Vec; // Bring Vec into scope
fn main() {
let two_sec = Duration::from_secs(2);
sleep(two_sec);
let mut map = HashMap::new();
map.insert("Key", 10);
println!("map: {:?}", map);
let mut queue = VecDeque::new();
queue.push_back(20);
println!("queue: {:?}", queue);
let vec: Vec<i32> = alloc::vec![1, 2, 3];
println!("vec: {:?}", vec);
let (x, y) = (5, 10);
match x.cmp(&y) {
Ordering::Less => println!("x is smaller"),
Ordering::Greater => println!("x is bigger"),
Ordering::Equal => println!("x and y are equal"),
}
}