A crate is the smallest amount of code that the Rust compiler considers at a time.
Two types of crates:
main
functionmain
function.A package is a bundle of one or more crates that provides a set of functionality.
A package contains a Cargo.toml file that describes how to build those crates.
Modules let us organize code within a crate for readability and easy reuse. Modules also allow us to control the access of items.
Both absolute and relative paths are followed by one or more identifiers separated by double colons (::
).
absolute path
is the full path starting from a crate root; for code from an external crate, the absolute path begins with the crate name, and for code from the current crate, it starts with the literal crate
.relative path
starts from the current module and uses self
, super
, or an identifier in the current module.In Rust, all items (functions, methods, structs, enums, modules, and constants) are private to parent modules by default. If you want to make an item like a function or struct private, you put it in a module.
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {
println!("add_to_waitlist")
}
}
}
pub fn eat_at_restaurant() {
// Absolute path
crate::front_of_house::hosting::add_to_waitlist();
// Relative path
front_of_house::hosting::add_to_waitlist();
}
use
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {
println!("add_to_waitlist")
}
}
}
mod customer {
/* Use must happened within the scope */
use crate::front_of_house::hosting::add_to_waitlist;
pub fn eat_at_restaurant() {
add_to_waitlist();
}
}
use std::fmt::Result;
use std::io::Result as IoResult; // `as` to provide an alias
fn function1() -> Result {
// --snip--
Ok(())
}
fn function2() -> IoResult<()> {
// --snip--
Ok(())
}
Add new dep in:Filename: Cargo.toml
rand = "0.8.5"
And then use them in your code:
use std::io;
use rand::Rng;
fn main() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1..=100);
//...
}
use std::cmp::Ordering;
use std::io;
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
use std::{cmp::Ordering, io};
use std::io;
use std::io::Write;
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
use std::io::{self, Write};
Or if you want to import all with glob operator *
:
use std::collections::*;
src/lib.rs
for a library crate or src/main.rs
for a binary crate) for code to compile.
mod garden;
. The compiler will look for the module’s code in these places:
mod garden
src/garden.rs
src/garden/mod.rs
mod vegetables;
in src/garden.rs
. The compiler will look for the submodule’s code within the directory named for the parent module in these places:
mod vegetables
, within curly brackets instead of the semicolonsrc/garden/vegetables.rs
src/garden/vegetables/mod.rs
Asparagus
type in the garden vegetables module would be found at crate::garden::vegetables::Asparagus
.
pub mod
instead of mod
. To make items within a public module public as well, use pub
before their declarations.
use
keyword: Within a scope, the use
keyword creates shortcuts to items to reduce repetition of long paths. In any scope that can refer to crate::garden::vegetables::Asparagus
, you can create a shortcut with use crate::garden::vegetables::Asparagus;
and from then on you only need to write Asparagus
to make use of that type in the scope.
backyard
├── Cargo.lock
├── Cargo.toml
└── src
├── garden
│ └── vegetables.rs
├── garden.rs
└── main.rs
Filename: src/main.rs
// Automatically find the crate 'src/garden/Asparagus'
use crate::garden::vegetables::Asparagus;
// Include the code from 'src/garden.rs'
pub mod garden;
fn main() {
let plant = Asparagus {};
println!("I'm growing {:?}!", plant);
}
Filename: src/garden.rs
pub mod vegetables;