mirror of
https://github.com/m-lamonaca/dev-notes.git
synced 2025-05-15 07:34:46 +00:00
parent
4c5c361db7
commit
75b392d778
134 changed files with 549 additions and 1495 deletions
143
docs/rust/cargo.md
Normal file
143
docs/rust/cargo.md
Normal file
|
@ -0,0 +1,143 @@
|
|||
# Cargo build system and package manager
|
||||
|
||||
## Creating a project
|
||||
|
||||
```ps1
|
||||
cargo new project_name # creates project folder and basic files
|
||||
cargo new --vcs=git project_name # init project as git repo
|
||||
```
|
||||
|
||||
## Building, Running & Checking a project
|
||||
|
||||
Inside the project directory:
|
||||
|
||||
```ps1
|
||||
cargo build # build project and download eventual needed dependencies
|
||||
cargo build --release # build project for release (build + optimisations)
|
||||
cargo run # executes the built executable
|
||||
cargo check # verifies buildability without producing an executable
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
In `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
crate_name = "<version_number>"
|
||||
```
|
||||
|
||||
## Code Organization
|
||||
|
||||
Rust has a number of features that allow to manage the code's organization, including which details are exposed, which details are private, and what names are in each scope in the programs.
|
||||
|
||||
These features, sometimes collectively referred to as the module system, include:
|
||||
|
||||
- **Packages**: A Cargo feature that allows to build, test, and share crates
|
||||
- **Crates**: A tree of modules that produces a library or executable
|
||||
- **Modules** and `use`: Allow to control the organization, scope, and privacy of paths
|
||||
- **Paths**: A way of naming an item, such as a struct, function, or module
|
||||
|
||||
### Packages & Crates
|
||||
|
||||
A crate is a binary or library. The crate root is a source file that the Rust compiler starts from and makes up the root module of he crate.
|
||||
A package is one or more crates that provide a set of functionality. A package contains a `Cargo.toml` file that describes how to build those crates.
|
||||
|
||||
Several rules determine what a package can contain. A package must contain `zero` or `one` **library crates** (`lib` ?), and no more.
|
||||
It can contain as many `binary` crates as you'd like, but it must contain at least one crate (either library or binary).
|
||||
|
||||
If a package contains `src/main.rs` and `src/lib.rs`, it has two crates: a library and a binary, both with the same name as the package.
|
||||
A package can have multiple binary crates by placing files in the `src/bin` directory: each file will be a separate binary crate.
|
||||
|
||||
A crate will group related functionality together in a scope so the functionality is easy to share between multiple projects.
|
||||
|
||||
Cargo follows a convention that `src/main.rs` is the crate root of a binary crate with the same name as the package.
|
||||
Likewise, Cargo knows that if the package directory contains `src/lib.rs`, the package contains a library crate with the same name as the package, and `src/lib.rs` is its crate root.
|
||||
|
||||
### Modules
|
||||
|
||||
Modules allow to organize code within a crate into groups for readability and easy reuse. Modules also control the privacy of items, which is whether an item can be used by outside code (*public*) or is an internal implementation detail and not available for outside use (*private*).
|
||||
|
||||
Define a module by starting with the `mod` keyword and then specify the name of the module and place curly brackets around the body of the module.
|
||||
Inside modules, it's possible to have other modules. Modules can also hold definitions for other items, such as structs, enums, constants, traits, or functions.
|
||||
|
||||
### Paths
|
||||
|
||||
A path can take two forms:
|
||||
|
||||
- An **absolute path** starts from a crate root by using a crate name or a literal crate.
|
||||
- A **relative path** starts from the current module and uses self, super, or an identifier in the current module.
|
||||
|
||||
Both absolute and relative paths are followed by one or more identifiers separated by double colons (`::`).
|
||||
|
||||
```rs
|
||||
module::function(); // rel path (same crate)
|
||||
super::function();; // rel path starting in outer module (same crate)
|
||||
|
||||
crate::module::function(); // abs path (same crate)
|
||||
<crate_name>::module::function(); // abs path (other crate)
|
||||
```
|
||||
|
||||
### Public vs Private
|
||||
|
||||
Modules aren’t useful only for organizing the code. They also define Rust’s privacy boundary:
|
||||
the line that encapsulates the implementation details external code isn’t allowed to know about, call, or rely on.
|
||||
So, to make an item like a function or struct private, put it in a module.
|
||||
|
||||
The way privacy works in Rust is that all items (functions, methods, structs, enums, modules, and constants) are *private by default*.
|
||||
Items in a parent module can’t use the private items inside child modules, but items in child modules can use the items in their ancestor modules.
|
||||
The reason is that child modules wrap and hide their implementation details, but the child modules can see the context in which they’re defined.
|
||||
|
||||
```rs
|
||||
mod module {
|
||||
fn func() {}
|
||||
}
|
||||
|
||||
// for a function to be accessible both module and function must be public
|
||||
pub mod public_module {
|
||||
pub fn public_func() {}
|
||||
}
|
||||
|
||||
mod file_level_module; // define a module for the whole file (same name as file)
|
||||
```
|
||||
|
||||
It's possible to use `pub` to designate *structs* and *enums* as public, but there are a few extra details.
|
||||
If `pub` is used before a struct definition, this makes the struct public, but the struct's fields will still be private.
|
||||
It's possible make each field public or not on a case-by-case basis.
|
||||
|
||||
In contrast, if an enum is made public, all of its variants are then public.
|
||||
|
||||
### `use`
|
||||
|
||||
```rs
|
||||
use <crate_name>::module; // import module (abs path, other crate)
|
||||
use crate::module; // import module (abs path, same crate)
|
||||
use self::module; // import module (rel path, same crate)
|
||||
|
||||
use <crate_name>::module as alias; // import module w/ aliases
|
||||
pub use <crate_name>::module; // re-exporting (import and make available to others)
|
||||
|
||||
use <crate_name>::module::{self, Item}; // import multiple paths
|
||||
pub use <crate_name>::module::*; // import all public items (Glob operator)
|
||||
|
||||
module::function(); // use func w/ shorter path
|
||||
```
|
||||
|
||||
## Separating into multiple files
|
||||
|
||||
```txt
|
||||
src
|
||||
|_main.rs --> default executable file
|
||||
|_lib.rs --> default library file
|
||||
|__module
|
||||
| |_mod.rs --> export submodules
|
||||
| |_submodule.rs --> submodule
|
||||
```
|
||||
|
||||
```rs
|
||||
// main.rs
|
||||
mod module; // declare module directory as a module
|
||||
|
||||
// mod.rs
|
||||
pub mod sub_module; // declare sub_module file as a module
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue