---
# System prepended metadata

title: Rust Note
tags: [rust]

---

# 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`