Tags: #rust #rustlang #learn
A package contains a Cargo.toml
file that describes how to build the crates defined within the package.
A package must contain at least one crate, it can be either a ‘library’ crate or a ‘binary’ crate.
A package can contain multiple binary crates, but can only one library crate.
A package can have multiple binary crates by placing files in the src/bin
directory: each file will be a separate binary crate.
To show Rust where to find an item in a module tree, we use a path in the same way we use a path when navigating a filesystem. If we want to call a function, we need to know its path.
This can be achieved using either an ‘absolute’ path or a ‘relative’ path.
Filename: src/lib.rs
mod front_of_house {
mod hosting {
fn 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();
}
You can define a module within the root library or binary crate or you can define them in separate files within the src
directory.
Filename: src/foo.rs
// foo module
pub mod bar {
pub trait Thing {
fn do_thing(&self);
}
pub fn baz() {
println!("baz called!")
}
#[derive(Debug)]
pub struct SomeStruct {
pub some_field: u8,
}
impl SomeStruct {
pub fn new(some_field: u8) -> SomeStruct {
SomeStruct { some_field }
}
}
impl Thing for SomeStruct {
fn do_thing(&self) {
println!("do a thing");
}
}
}
Filename: src/main.rs
mod foo;
use crate::foo::bar;
use crate::foo::bar::Thing; // you must import the trait implemented for SomeStruct
fn main() {
bar::baz();
let ss = bar::SomeStruct::new(123);
println!("{:?}", ss);
println!("{}", ss.some_field);
ss.do_thing();
}
NOTE: Using a semicolon after
mod foo
rather than using a block{...}
tells Rust to load the contents of the module from another file with the same name as the module.