Rustチートシート

# Rustチートシート
- あくまで自分用なので雑なのは許してください（学んだものから更新しているので統一性はありません…）
- 2022/12/20 リアルタイムで勉強中なのでどんどん更新していきます

## 変数
- ミュータブルとイミュータブル
    定義した変数に再代入したい時は```mut```をつける
    ```rs
    fn main(){
        let mut s1 = String::from("hell");
        s1 = String::from("hello");
        let s2 = ("world");
        let s3 = s1 + s2;
        println!("{}", s3);
    }
    ```

## 所有権
```rs
fn main(){
    let s1: String = String::from("Hello");
    let s2: &str = "World";
    println!("{}", add_string(s1, s2));
}

//sは変更したいのでミュータブルのString型で受け取る
//tは変更するう必要がないので参照だけを受け取る
fn add_string(s: String, t: &str) -> String{
    s + t
}
```

## 結合
### 文字列結合
- 結合される側はString型、結合する側は文字列リテラル（結合される側は変更されるためミュータブルである必要があるが、結合する側は変更されないのでイミュータブルでよい）
    ```rs
    fn main(){
        let mut s1 = String::from("hello");
        let s2 = ("world");
        let s3 = s1 + s2;
        println!("{}", s3);
    }
    ```

## 構造体
- 定義
    ```rs
    struct User {
        username: String,
        email: String,
        sign_in_count: u64,
        active: bool,
    }
    ```
- 構造体メソッド定義
    ```rs
    impl User{
        //引数にselfを持たせないことでstaticメソッドとして定義できる
        pub fn new(username: String, email: String, sign_in_count: u64, active: bool) -> Self{
            Self{username: username, email: email, sign_in_count: sign_in_count, active: active}
        }
        //通常の構造体メソッド
        pub fn print_name(self){
            println!("{}", self.username);
        }
    }
    ```
- メソッド呼び出し
    ```rs
    let user: User = User::new(String::from("revioness"), String::from("revioness.outlook.jp"), 1, true);
    user.print_name();
    ```
- インスタンス化
    ```rs
    let user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
    ```
- 参照
    ```rs
    println!("email:{}", user1.email);
    ```
- 値の変更
    ```rs
    let mut user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
    ```
    今まで何度も言っているように、```let 変数名```で定義したものはイミュータブルになるので、値の変更ができない
    なので```mut```をつけてミュータブルにする
    構造体のこの変数だけミュータブルに！といったことはできない
    ```rs
    user1.username = String::from("test123");
    ```
- 省略形
    ```rs
    let mut user1 =  User {
                email: String::from("someone@example.com"),
                username: String::from("someusername123"),
                active: true,
                sign_in_count: 1,
            };
    let mut user2 =  User {
                email: String::from("someone2@example.com"),
                username: String::from("someusername1234"),
                ..user1
            };
    ```
    ```active```と```sign_in_count```がuser1と同じ値が入る

## タプル
```rs
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
```
この場合、中の構造は同じだが、型はColor型とPoint型に分かれる

## println!
- そのまま出力
    ```rs
    println!("rect1 is {}", 1);
    ```
- 構造体の出力
    ```rs
    struct Rectangle {
        width: u32,
        height: u32,
    }

    fn main() {
        let rect1 = Rectangle { width: 30, height: 50 };

        // rect1は{}です
        println!("rect1 is {:?}", rect1);
    }
    ```
    ```bash
    rect1 is Rectangle { width: 30, height: 50 }
    ```
    さらに見やすく
    ```rs
    struct Rectangle {
        width: u32,
        height: u32,
    }

    fn main() {
        let rect1 = Rectangle { width: 30, height: 50 };

        // rect1は{}です
        println!("rect1 is {:#?}", rect1);
    }
    ```
    ```bash
    rect1 is Rectangle {
        width: 30,
        height: 50,
    }
    ```

## ファイル入出力
### ファイル読み込み

```rs
use std::fs;
use std::error;
use std::io::Write;

//Stringで読み込み
let content = fs::read_to_string("ファイルパス")?;

//書き込み
let mut file = fs::File::create("ファイルパス")?;
file.write_all(buf).unwrap();
```

## json

```rs
//Cargo.toml
[dependencies]
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.91"

//src
use serde::{Serialize, Deserialize};

//構造体で継承
#[derive(Serialize, Deserialize)]


let json = serde_json::to_string("json文字列").unwrap();
```

## Logger
- env_logger
    ```rs
    //Cargo.toml
    [dependencies]
    log = "0.4.0"
    env_logger = "0.10.0"

    //src
    use env_logger;
    use log::{error, warn, info, debug};

    //デバッグレベル設定・初期化
    env::set_var("RUST_LOG", "info");
    env_logger::init();

    info!("コメント");
    ```
    ```bash
    #出力
    [2022-12-29T14:42:24Z INFO  アプリ名] コメント
    ```