|
2 | 2 |
|
3 | 3 | {{#include ../banners/hacktricks-training.md}} |
4 | 4 |
|
| 5 | +### Ownership of variables |
| 6 | + |
| 7 | +Memory is managed through a system of ownership with the following rules that the compiler checks at compile time: |
| 8 | + |
| 9 | +1. Each value in Rust has a variable that's called its owner. |
| 10 | +2. There can only be one owner at a time. |
| 11 | +3. When the owner goes out of scope, the value will be dropped. |
| 12 | + |
| 13 | +```rust |
| 14 | +fn main() { |
| 15 | + let student_age: u32 = 20; |
| 16 | + { // Scope of a variable is within the block it is declared in, which is denoted by brackets |
| 17 | + let teacher_age: u32 = 41; |
| 18 | + println!("The student is {} and teacher is {}", student_age, teacher_age); |
| 19 | + } // when an owning variable goes out of scope, it will be dropped |
| 20 | + |
| 21 | + // println!("the teacher is {}", teacher_age); // this will not work as teacher_age has been dropped |
| 22 | +} |
| 23 | +``` |
| 24 | + |
| 25 | + |
| 26 | + |
5 | 27 | ### Generic Types |
6 | 28 |
|
7 | 29 | Create a struct where 1 of their values could be any type |
@@ -34,6 +56,24 @@ pub enum Option<T> { |
34 | 56 |
|
35 | 57 | You can use functions such as `is_some()` or `is_none()` to check the value of the Option. |
36 | 58 |
|
| 59 | + |
| 60 | +### Result, Ok & Err |
| 61 | + |
| 62 | +Used for returning and propagating errors |
| 63 | + |
| 64 | +```rust |
| 65 | +pub enum Result<T, E> { |
| 66 | + Ok(T), |
| 67 | + Err(E), |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +You can use functions such as `is_ok()` or `is_err()` to check the value of the result |
| 72 | + |
| 73 | +The `Option` enum should be used in situations where a value might not exist (be `None`). |
| 74 | +The `Result` enum should be used in situations where you do something that might go wrong |
| 75 | + |
| 76 | + |
37 | 77 | ### Macros |
38 | 78 |
|
39 | 79 | Macros are more powerful than functions because they expand to produce more code than the code you’ve written manually. For example, a function signature must declare the number and type of parameters the function has. Macros, on the other hand, can take a variable number of parameters: we can call `println!("hello")` with one argument or `println!("hello {}", name)` with two arguments. Also, macros are expanded before the compiler interprets the meaning of the code, so a macro can, for example, implement a trait on a given type. A function can’t, because it gets called at runtime and a trait needs to be implemented at compile time. |
@@ -363,6 +403,16 @@ Integrate it in CI and fail on `--deny warnings`. |
363 | 403 |
|
364 | 404 | `cargo deny check advisories` offers similar functionality plus licence and ban-list checks. |
365 | 405 |
|
| 406 | +#### Code coverage with cargo-tarpaulin |
| 407 | + |
| 408 | +`cargo tarpaulin` is a code coverage reporting tool for the Cargo build system |
| 409 | + |
| 410 | +```bash |
| 411 | +cargo binstall cargo-tarpaulin |
| 412 | +cargo tarpaulin # no options are required, if no root directory is defined Tarpaulin will run in the current working directory. |
| 413 | +``` |
| 414 | +On Linux, Tarpaulin's default tracing backend is still Ptrace and will only work on x86_64 processors. This can be changed to the llvm coverage instrumentation with `--engine llvm`. For Mac and Windows, this is the default collection method. |
| 415 | + |
366 | 416 | #### Supply-chain verification with cargo-vet (2024) |
367 | 417 |
|
368 | 418 | `cargo vet` records a review hash for every crate you import and prevents unnoticed upgrades: |
|
0 commit comments