Rust Memo

#### 文字列(String)の作成
```rust                                                                 
1. String::from("This is a pen");
2. "This is a pen".to_string();      
3. let s: String = "This is a pen".into(); // type annotations needed
4. "This is a pen".to_owned();                     
5. format!("This is a pen");
```
- [The fastest way to make Rust Strings](https://brokenco.de/2022/10/28/rust-strings.html)

#### 型や変数のサイズを求める(sizeof)
```rust
1.
println!("{}", std::mem::size_of::<String>());

2.
let v = 17;
println!("{}", std::mem::size_of_val(&v)); // &が必要

// 24
// 4
```
- [std::mem::size_of](https://doc.rust-lang.org/std/mem/fn.size_of.html)
- [std::mem::size_of_val](https://doc.rust-lang.org/std/mem/fn.size_of_val.html)

#### 変数の型を求める(typeof)
```rust
fn type_of<T>(_: T) -> &'static str {
    std::any::type_name::<T>()
}

let x = 123;
println!("{}", type_of(x));

// i32
```
- [std::any::type_name](https://doc.rust-lang.org/std/any/fn.type_name.html)

#### 配列(Array)の初期化
```rust
let array: [&str; 3] = ["one", "two", "three"];
// ["one", "two", "three"]
let array = ["one", "two", "three"];
// ["one", "two", "three"]
let array = ["one"; 3]; // [&str; 3]
// ["one", "one", "one"]
```

#### ベクター(Vector)の初期化
```rust
let mut v: Vec<i32> = Vec::new();
v.push(1);
v.push(2);
v.push(3);
// [1, 2, 3]
let mut v = Vec::with_capacity(8);
// v.capacity() == 8, v.len() == 0
let v = vec![1, 2, 3]; // Vec<i32>
// [1, 2, 3]
// v.capacity() == 3, v.len() == 3
let v = vec![0; 3]; // Vec<i32>
// [0, 0, 0]
// v.capacity() == 3, v.len() == 3
```

#### タプル(Tuple)の使い方
```rust
let t = (1, "hello", 4.5, true); // (i32, &str, f64, bool)

let (a, b, c, d) = t; // it's called destructuring
println!("{} {} {} {}", a, b, c, d);
// 1 hello 4.5 true

let (_, _, x, z) = t;
println!("{} {}", x, z);
// 4.5 true
```

#### match(パターン記法など)
- [パターン記法](https://doc.rust-jp.rs/book-ja/ch18-03-pattern-syntax.html)

#### if let, while let
```rust
// --- if let ---
let var = Some(0);
if let Some(x) = var {
    println!("{}", x);
}
// 0

// --- if let ---
let var: Option<i32> = None; // let var = None::<i32>; (同じ)
if let None = var {
    println!("None");
}
// None

// 上もいけるが、こっちの方が良さげ
// if var.is_none() {
//     println!("None");
// }

// --- while let ---
let mut optional = Some(0);
while let Some(i) = optional {
    if i > 3 {
        println!("Greater than 3, quit!");
        optional = None;
    } else {
        println!("`i` is `{:?}`. Try again.", i);
        optional = Some(i + 1);
    }
}
// `i` is `0`. Try again.
// `i` is `1`. Try again.
// `i` is `2`. Try again.
// `i` is `3`. Try again.
// Greater than 3, quit!
```
- [Rustの「if let」とは何なのか？](https://qiita.com/plotter/items/0d8dc2782f21178d64f1)

#### let else
```rust
fn get_count_item(s: &str) -> (u64, &str) {
    let mut it = s.split(' ');
    let (Some(count_str), Some(item)) = (it.next(), it.next()) else {
        panic!("Can't segment count item pair: '{s}'");
    };
    let Ok(count) = u64::from_str(count_str) else {
        panic!("Can't parse integer: '{count_str}'");
    };
    (count, item)
}

assert_eq!(get_count_item("3 chairs"), (3, "chairs"));
```
- [let-else文](https://qiita.com/plotter/items/0d8dc2782f21178d64f1#20221110%E8%BF%BD%E8%A8%98-let-else%E6%96%87)

#### 生識別子、生文字列リテラル、バイト文字列リテラル(r#, br#)
- [生識別子](https://doc.rust-jp.rs/book-ja/appendix-01-keywords.html#%E7%94%9F%E8%AD%98%E5%88%A5%E5%AD%90)
- [More about printing](https://dhghomon.github.io/easy_rust/Chapter_13.html?highlight=r%23#more-about-printing)
- [演算子以外のシンボル](https://doc.rust-jp.rs/book-ja/appendix-02-operators.html?highlight=r%23#%E6%BC%94%E7%AE%97%E5%AD%90%E4%BB%A5%E5%A4%96%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%9C%E3%83%AB)

#### Option 型と Result 型
- [Option 型とは？](https://maku77.github.io/p/9m6m5m3/)
- [Result 型とは？](https://maku77.github.io/p/us2ahpw/)
- [Option and Result](https://dhghomon.github.io/easy_rust/Chapter_31.html)

#### Struct (destructuring)
```rust
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let papa = Person {
        name: "Tarou".to_string(),
        age: 17,
    };

    let Person {
        name: person_name,
        age: person_age,
    } = papa;
    println!("{} {}", person_name, person_age);

    // 変数名を省略できる
    // let Person { name, age } = papa;
    // println!("{} {}", name, age);
}
```

#### Generics (ジェネリックス)
```rust
use std::cmp::PartialOrd;
use std::fmt::Display;

// fn compare_and_display<T: Display, U: Display + PartialOrd>(msg: T, num_1: U, num_2: U)
fn compare_and_display<T, U>(msg: T, num_1: U, num_2: U)
where
    T: Display,
    U: Display + PartialOrd,
{
    println!("{}! {} > {}: {}", msg, num_1, num_2, num_1 > num_2);
}

fn main() {
    compare_and_display("Listen up", 9, 8);
    compare_and_display("Listen up".to_string(), 9, 8);
    compare_and_display(9999, 9.0, 12.5);
}
// Listen up! 9 > 8: true
// Listen up! 9 > 8: true
// 9999! 9 > 12.5: false
```

#### 整数と実数の最小値(min)と最大値(max)
```rust
println!("   i8| {: >40} | {: >39} |", std::i8::MIN, std::i8::MAX);
println!("  i16| {: >40} | {: >39} |", std::i16::MIN, std::i16::MAX);
println!("  i32| {: >40} | {: >39} |", std::i32::MIN, std::i32::MAX);
println!("  i64| {: >40} | {: >39} |", std::i64::MIN, std::i64::MAX);
println!(" i128| {: >40} | {: >39} |", std::i128::MIN, std::i128::MAX);
println!( "isize| {: >40} | {: >39} |", std::isize::MIN, std::isize::MAX);
println!("   u8| {: >40} | {: >39} |", std::u8::MIN, std::u8::MAX);
println!("  u16| {: >40} | {: >39} |", std::u16::MIN, std::u16::MAX);
println!("  u32| {: >40} | {: >39} |", std::u32::MIN, std::u32::MAX);
println!("  u64| {: >40} | {: >39} |", std::u64::MIN, std::u64::MAX);
println!(" u128| {: >40} | {: >39} |", std::u128::MIN, std::u128::MAX);
println!( "usize| {: >40} | {: >39} |", std::usize::MIN, std::usize::MAX);
println!("  f32| {: >40e} | {: >39e} |", std::f32::MIN, std::f32::MAX);
println!("  f64| {: >40e} | {: >39e} |", std::f64::MIN, std::f64::MAX);
//    i8|                                     -128 |                                     127 |
//   i16|                                   -32768 |                                   32767 |
//   i32|                              -2147483648 |                              2147483647 |
//   i64|                     -9223372036854775808 |                     9223372036854775807 |
//  i128| -170141183460469231731687303715884105728 | 170141183460469231731687303715884105727 |
// isize|                     -9223372036854775808 |                     9223372036854775807 |
//    u8|                                        0 |                                     255 |
//   u16|                                        0 |                                   65535 |
//   u32|                                        0 |                              4294967295 |
//   u64|                                        0 |                    18446744073709551615 |
//  u128|                                        0 | 340282366920938463463374607431768211455 |
// usize|                                        0 |                    18446744073709551615 |
//   f32|                            -3.4028235e38 |                            3.4028235e38 |
//   f64|                  -1.7976931348623157e308 |                  1.7976931348623157e308 |
```