R1: Cargo Flashcards
What is Cargo?
Cargo is Rust’s build system and package manager. It can: build your code, download the libraries your code depends on, and build those libraries.
Cmd: cargo new <project name>
We can create a project. You’ll see that Cargo has generated two files and one directory for us: a Cargo.toml file and a src directory with a main.rs file inside.
Cmd: cargo new --vcs=git hello_cargo
Same as cargo new <project name>
but overrides current git config files.
What does the Cargo.toml contain?
This file is in the TOML (Tom’s Obvious, Minimal Language) format, which is Cargo’s configuration format.
Example:
[package]
name = “hello_cargo”
version = “0.1.0”
edition = “2021”
See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
What is [package] in Cargo.toml?
The first line, [package], is a section heading that indicates that the following statements are configuring a package.
What is [dependencies] in Cargo.toml?
Is the start of a section for you to list any of your project’s dependencies. In Rust, packages of code are referred to as crates.
Cmd: cargo build
We can build a project
Cmd: cargo run
We can build and run a project in one step
Cmd: cargo check
We can build a project without producing a binary to check for errors using
target/debug
directory
Instead of saving the result of the build in the same directory as our code, Cargo stores it in the target/debug directory.
Cmd: cargo build --release
?
When your project is finally ready for release, you can use cargo build –release to compile it with optimizations. This command will create an executable in target/release instead of target/debug.
Cmd: cargo build --release
?
When your project is finally ready for release, you can use cargo build –release to compile it with optimizations. This command will create an executable in target/release instead of target/debug.
module system
Rust has a number of features that allow you to manage your code’s organization, including which details are exposed, which details are private, and what names are in each scope in your programs.
These features include:
- Packages: A Cargo feature that lets you build, test, and share crates
- Crates: A tree of modules that produces a library or executable
- Modules and use: Let you control the organization, scope, and privacy of paths
- Paths: A way of naming an item, such as a struct, function, or module
crate
A crate is the smallest amount of code that the Rust compiler considers at a time. A crate can come in one of two forms:
- Binary crates: are programs you can compile to an executable that you can run, such as a command-line program or a server.
- Library crates don’t have a main function, and they don’t compile to an executable. Instead, they define functionality intended to be shared with multiple projects.
crate root
The crate root is a source file that the Rust compiler starts from and makes up the root module of your crate (usually src/lib.rs for a library crate or src/main.rs for a binary crate).
package
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.
Declaring submodules
Declaring modules: In the crate root file, you can declare new modules; say, you declare a “garden” module with mod garden;.
Once a module is part of your crate, you can refer to code in that module from anywhere else in that same crate, as long as the privacy rules allow, using the path to the code. For example, an Asparagus type in the garden vegetables module would be found at crate::garden::vegetables::Asparagus.
Private vs public modules
Code within a module is private from its parent modules by default. To make a module public, declare it with pub mod instead of mod.
use keyword
The 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
Here we create a binary crate named backyard that illustrates these rules. The crate’s directory, also named backyard, contains these files and directories:
backyard ├── Cargo.lock ├── Cargo.toml └── src ├── garden │ └── vegetables.rs ├── garden.rs └── main.rs
Example of modules use
``` src/main.rs
use crate::garden::vegetables::Asparagus;
pub mod garden;
fn main() {
let plant = Asparagus {};
println!(“I’m growing {:?}!”, plant);
}
``` src/garden.rs pub mod vegetables;
src/garden/vegetables.rs #[derive(Debug)] pub struct Asparagus {}
Grouping Related Code in Modules
Examples of fs tree:
crate └── front_of_house ├── hosting │ ├── add_to_waitlist │ └── seat_at_table └── serving ├── take_order ├── serve_order └── take_payment
Examples of module:
mod front_of_house { mod hosting { fn add_to_waitlist() {} fn seat_at_table() {} } mod serving { fn take_order() {} fn serve_order() {} fn take_payment() {} } }
absolute path
- An 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.
Emod 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
- A relative path: starts from the current module and uses self, super, or an identifier in the current module.
Emod front_of_house { mod hosting { fn add_to_waitlist() {} } } pub fn eat_at_restaurant() { // Relative path front_of_house::hosting::add_to_waitlist();