# Rust Note
{%hackmd @RintarouTW/About %}
[The Rust Programming Language](https://doc.rust-lang.org/book/)
[Command line apps in Rust](https://rust-cli.github.io/book/index.html)
[Rust and WebAssembly](https://rustwasm.github.io/docs/book/introduction.html)
[The Unstable Book](https://doc.rust-lang.org/nightly/unstable-book/the-unstable-book.html)
[The Rust Reference](https://doc.rust-lang.org/reference/introduction.html)
[The Rust Sandard Library](https://doc.rust-lang.org/std/index.html)
## Environment
rustc - compiler
cargo - package manager
```!bash
cargo new project
cargo build --release // optimized
cargo build // for dev, nonoptimized, including symbols
cargo run
```
## Package Repository
https://crates.io/
update packages
```!bash
cargo update
```
## Packages, Crates, Modules and Workspaces
- Packages: A Cargo feature that lets you build, test and share crates.
- Creates: A tree of modules that produces a library or executale.
- 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.
### Package
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.
- src/main.rs : the crate root of a binary crate with the same name as the package.
- src/lib.rs : the package contains a library crate with the same name as the pacakge. it's the crate root of a library.
if a package contains both src/main.rs and src/lib.rs, then it has two crates: a library and a binary.
### Modules
paths that allow you to name items;
- the **use** keyword that brings a path into scope;
- the **pub** keyword to make items as public
- the **as** keyword ...
Modules let us organize code within a crate into groups for reability and easy reuse.
```
cargo new --lib library_name
```
Example:
**src/lib.rs**
```!rust
mod front_of_house {
mod hosting {
fn add_to_waitlist() {}
fn ...
}
mod serving {
fn ...
}
}
```
define a module with **mod** keyword.
the entire module tree is rooted under the implicit module named **crate**.
### Path
Paths for referring to an item in the module tree.
- absolute path: starts from a crate root by using a crate name or literal crate.
- relative path: starts from the current module and use **self**, **super**, or an identifier in the current module.
Ex:
```!rust
pub fn test() {
// absolute path
crate::front_of_house::hosting::add_to_waitlist();
// relative path
front_of_house::hosting::add_to_waitlist();
}
```
**Starting Relative Paths with super**
```!rust
fn serve_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
super::serve_order();
}
fn cook_order() {}
}
fn main() {}
```
## Languages
**Variables are immutable by defaul**
```!rust
let a = 1; // immutable
let mut b = 2; // mutable
const C = 3; // constant and should be in upper cases.
```
**Loop**
```!rust
loop {
break;
continue;
}
```
**traits**
build documentation of packages
```!bash
cargo doc --open
```
**Shadowing**
redefine is allowed in Rust, called **Shadowing**.
```!rust
let a = "abc";
let a : u32 = 123;
```
```!rust
let x = 5;
let x = x + 1;
let x = x * 2;
println!("The value of x is: {}", x);
x = 12
```
shadowing is actually creating another veriable internally by the rustc. it's not the same with **mut**.
### Data Types
**Scalar Types**
```
i8, u8
i16, u16
i32, u32
i64, u64
i128, u128
isize, usize // by arch
f32, f64
```
**Number Operations**
$$
\cases{
+\\
-\\
*\\
/\\
\%\\
}
$$
**Character Type**
single quote, unicode support
```!rust
let c = 'z';
```
**Tuple**
```!rust
let tup : (i32, u64, f32) = (1, 2, 3.0);
let (x, y, z) = tup;
```
**expression vs statement**
expression without ; as return value, and statement required ;
**functions**
```!rust
fn func(x: type) -> return_type {
...
return value with expression
}
```
**control flow**
- if with no ()
- loop {}
- for {}
- while {}
**Result<T, E>**
```!rust
enum Result<T, E>{
Ok(T),
Err(E),
}
```
**Option<T>**
```!rust
enum Option{
Some(Val),
None,
}
```
## Ownership Rules
- Each value in Rust has a variable that's called it's owner.
- There can only be one owner at a time.
- When the owner goes out of scope, the value will be dropped.
:::warning
value's owner would be moved to function(), unless using & reference instead.
:::
call by reference was called **borrowing** in Rust.
Reference is like variable as immutable by default.
**Mutable Reference**
:::warning
mutable reference can only be borrowed once at a time.
:::
this ristriction is to prevent data races at compile time.
## Memory
Much more strict than other languages.
- Return memory once it's not used in code level. not even the end of the function.
- Ownership would change to another function by simply (call by value in C++).
### Collections
- Vec
- String
- HashMap
## Error Handling
```!rust
enum Result<T, E> {
Ok(T),
Err(E),
}
```
## Trait
like interface. but,
- default implementation is allowed.
- imp XXX for struct/enum
- strict to local implementation. no overwrite to other's implementation.
## Smart Pointer in Rust
- Deref Trait : Make an instance of smart pointer behave like a reference.
- Drop Trait : Allow you to customize ur code to run when an instance of smart pointer is out of scope.
Common smart pointers in std,
- Box<T> for allocating values on the heap
- Rc<T>, a reference counting type that enables multiple ownership
- Ref<T> and RefMut<T>, accessed through RefCell<T>, a type that enforces the borrowing rules at runtime instead of compile time
## Unsafe Rust
## Todo
### how enum() hold the value in memory?
### read vec![] docs to clearify
```!rust
let vecs = vec![...];
for v in vecs {
}
for v in vecs.iter() {
}
```
### take()
take the value from the Box<T>
### unwrap()?
### object-safe?? from what??
need definition.
### what's the difference between String and str?
**String** is a smart pointer implementation of String.
**str** is "String Slice"
a &str is two values: the address(as_ptr) of the str and its length(len), we can know the size of a &str value at compile time: it’s twice the length of a usize.
&T is a reference(pointer) to the T typed data structure.
### is there a way to show &ref value(raw pointer)?
Dereference a raw pointer in unsafe Rust.
```!rust
fn main() {
let mut num = 5;
let r1 = &num as *const i32;
let r2 = &mut num as *mut i32;
}
```
### match only match one arm
### module files
src/lib.rs
```!rust
mod front_of_house;
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}
```
src/front_of_house.rs
```!rust
... implmentations of front_of_house module
```
### Multi-threads and channels
```!rust
let (tx, rx) = mpsc:: ...
// blocking
tx.send(val)
rs.recv()
// nonblocking
tx.send_...
rx.recv_...
```
### Study more about Rust Macros.
[Macros By Example](https://doc.rust-lang.org/reference/macros-by-example.html)
[The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html)
- ast (syntax tree)
- macro_rules!
- procedural macro
- attribute macro
## Terms
**unit-like**
() is actually a tuple without numbers.
**tuple struct**
struct Foo();
**fn**
fn is actually a function pointer.
## Core Traits
### Trait core::convert::From
https://doc.rust-lang.org/nightly/core/convert/trait.From.html
value-to-value conversions
Implementing **From** automatically provides one with an implementation of **Into**.
- From<T> for U implies \<U> for T
- From is reflexive, so From<T> for T is implemented.
ex:
```!rust
use std::fs;
use std::io;
use std::num;
enum CliError {
IoError(io::Error),
ParseError(num::ParseIntError),
}
impl From<io::Error> for CliError {
fn from(error: io::Error) -> Self {
CliError::IoError(error)
}
}
impl From<num::ParseIntError> for CliError {
fn from(error: num::ParseIntError) -> Self {
CliError::ParseError(error)
}
}
fn open_and_parse_file(file_name: &str) -> Result<i32, CliError> {
let mut contents = fs::read_to_string(&file_name)?;
let num: i32 = contents.trim().parse()?;
Ok(num)
}
```
###### tags: `rust`