RustとC++を比較

# 文法
## 変数宣言
```rust:rust
let x : i32 = 1;
let y = 1; // 型推論
let mut z = 1; // 変更可能な値
```

```c++:c++
const int x = 1;
const auto y = 1;
int z = 1;
```

Rustの`mut`とC++の**非**`const`はほぼ同じ意味をもつ。

## 参照
```rust:rust
let x : i32 = 1;
let y : &i32 = &x;
let z : &&i32 = &&x;
let zz : &i32 = &&x; // 参照の参照は参照に潰すことができる (Deref の型強制)
assert_eq!(x, *y); // 参照の解決
assert_eq!(x, **zz);
```

```c++:c++
const int x = 1;
const int& y = x;
const int& z = y; // 参照の参照は参照
```

C++では`T`と`T&`とで互いに暗黙の型変換が発生するが,
Rustでは`& : T -> &T`と `* : &T -> T`で明示的に変換する必要がある。

## 参照先が変更可能な参照
```rust:rust
let x : i32 = 1;
{
    let y : &mut i32 = &mut x; // &mut: T -> &mut T
    *y = 5;
}
assert_eq!(x, 5);
```

```c++:c++
int x = 1;
{
    int& y = x;
    y = 5;
}
```

`&mut`参照は, 参照先の値を変更できる

### mut参照の制限
```rust:rust
let mut x : i32 = 1;
let y : &i32 = &x; // OK
let z : &i32 = &x; // OK
// let w : &mut i32 = &mut x // NG
```
Rustではある値(`T`)にすでに参照(`&T`)またはmut参照(`&mut T`)がある時,
新しく**mut参照(`&mut T`)は作れない**。

これは主にデータレースを防ぐため。

## 関数宣言
```rust:rust
fn plus(x : i32, y : i32) -> i32 {
    x + y // 式の結果を返す場合 ; をつけない。 つけると () を返す
}

fn say_hello() { // 省略すると返り値は ()
    println!("hello");
}
```

```c++:c++
//c++
i32 plus(int x, int y) {
    return x + y;
}

void say_hello() {
    std::cout << "hello" << std::endl;
}
```

## Hello, world
```rust:rust
fn main() {
    println!("Hello, world");
}
```

```c++:c++
#include <iostream>
int main() {
    std::cout<< "Hello, world" << std::endl;
}
```

## 制御構造

### if / if let
```rust:rust
let res = if x == 3 {
    -3
} else if x == 2 {
    -2
} else {
    0
}
```

```c++:c++
int res;
if (x == 3) {
    res = -3;
} else if (x == 2) {
    res = -2;
} else {
    res = 0;
}
```

#### パターンマッチに成功する時ブロックを実行

```rust:rust
let x = Some(3);
if let Some(v) = x {
    assert_eq!(v, 3);
}
```

```c++:c++
ない
```
Rustにしかないやつ。Goとかにある条件式前束縛とは異なる

### while / while let
```rust:rust
let mut x = 5;
while x != 0 {
    x -= 1; // デクリメントはない
}
```

```c++:c++
int x = 5
while (x != 3) {
    x--;
}
```

```rust:rust
while if Some(v) = x {

}
```

```c++:c++
ない
```

### 無限ループ
```rust:rust
loop {
}
```
```c++:c++
while (true) {
}
```

# 型
## 基本型

|備考|Rust|C++|
|---|---|---|
|整数型|`i8`, `i16`, `i32`, `i64`| `int8_t`, `int16_t` ...|
| @ |(`2`), `2i32` ...|(`2`, `2l` ...)|
|非負整数型|`u8`, `u16`, `u32`, `u64`| `uint8_t`, `uint16_t` ...|
| @ |`2u32` ...|(`2u`)|
|ポインタサイズ整数|`isize`, `usize`| `intptr_t`, `uintptr_t`|
| @ |`2isize`, `2usize`||
|小数型|`f32`, `f64`| [提案中(?)](https://cpplover.blogspot.jp/2013/05/2013-05-post-bristol-mailing.html) `double`|
| @ |`2.0f32`, `2.0f64`|(`2.0`, `2.0ld` ...)|
|論理値型|`bool`|`bool`|
| @ |`true`, `false`|`true`, `false`|
|文字型|`char`|`char32_t`|
| @ |`'a'`, `'あ'`|`U'a'`, `U'あ'`|
|固定長配列型|`[T; N]`|`T[]`|
| @ |`[0, 1]`, `[2; 3]` |`{1, 2}`, (`{2, 2, 2}`)|
|スライス|`&[T]`||
| @ |`arr[1..3]` `arr[..]`||
|タプル|`(T, U, V)`|`tuple<T, U, V>`|
| @ |`(1, 'a', 1.0f32)`|`make_tuple(1, 'a', 1.0)`|
|無|`()`|`void`|
| @ |`()`||
|参照|`&T`, `&mut T`|`const T &`, `T &`|
| @ |`&x`, `&mut x`||
|生ポインタ|`*const T`, `*mut T`|`const T *`, `T *`|
| @ |`&x as *const i32`|`&x`|

## 構造体
```rust:rust
struct User {
    name: String,
    age: u64,
}
let u : User = User { name: String::from("Alice"), age: 17 };
assert_eq!(u.age, 17);
```

```c++:c++
struct User {
    string: name,
    uint64_t: age
}
cosnt User u { "Alice", 17 };
```

### メソッド
```rust:rust
impl User {
    fn hello(&self) { // self, &self, &mut self の3パターンある。
        println!("I am {}.", self.name);
    }
}
let u : User = User { name: String::from("Alice"), age: 17 };
u.hello();
```

```c++:c++
struct User {
    /*...*/
    hello() {
        std::cout << "I am " << this->name, << "." << std::endl;
    }
}
cosnt User u { "Alice", 17 };
u.hello();
```

### 型メソッド
```rust:rust
impl User {
    fn me(age : u64) -> Self {
        User { name: String::from("Alice"), age: me }
    }
}
assert_eq!(User::me(10).name, String::from("Alice"));
```

```c++:c++
struct User {
    /*...*/
    static User me (int age) {
        return User{ "Alice", 17 }
    }
}
```
### 演算子オーバオーロード
```rust:rust
impl PartialEq<Self> for User {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name && self.age == other.age
    }
}

let u : User = User { name: String::from("Alice"), age: 17 };
let v : User = User { name: String::from("Alice"), age: 17 };
assert!(u == v);
```

```c++:c++
struct User {
    /*...*/
    bool operator==(const User& that) const {
        return this.name == that.name && this.age == this.age;
    }
}

User v{"A", 17}, u{"A", 17};
v == u;
```

なお `#[derive(PartialEq)]` で自動生成される。

## 列挙体
```rust:rust
enum IpAddrKind {
    V4,
    V6,
}
let ip : IpAddrKind = IpAddrKind::V4;
```

```c++:c++
enum IpAddrKind {
    V4,
    V6
}
IpAddrKind ip = V4;
```

### 直積型
```rust:rust
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Color(i32, i32, i32),
}
let mes : Message = Message::Move{ x: 1, y: 2 };
let mes = Message::Color(0, 1, 2);
```

```c++:c++
ない
```

### パターンマッチ
```rust:rust
let s = match mes {
    Message::Move => "move",
    Message::Color => "color",
    _ => "other",
}
```

```c++:c++
ない
```

#### パターンマッチで参照を得る, 外す
```rust:rust
let mut x : i32 = 1;

// 以下の文はブロックで囲んでいる
{ let ref y : i32 = x; } // 参照を得る y : &i32
{ let y : &i32 = &x; } // 上と同じ

{ let ref mut z : i32 = x; } // 変更可能参照を得る z : &mut i32
{ let z : &mut i32 = &mut x; } // 上と同じ

{ let (ref y, ref z) : (i32, i32) = (1, 2); } // パターンマッチで使う y, z : &32

{ let &r : &i32 = &x; } // &にマッチすると参照が外れる r : i32
{ let r : i32 = x; } // 上と同じ
```

+ `ref`, `ref mut`パターンは, 参照を得るパターン
+ `&`, `&mut`パターンは, 参照を外すパターン

# トレイト

https://llogiq.github.io/2015/07/30/traits.html

## 演算子オーバーロード
- 算術演算子: `Add`, `Sub` , `Neg` , `Mul` , `Div` , `Rem`
- 他の演算子: `Not` , `BitAnd` , `BitOr` , `BitXor` , `Shl` , `Shr`
- 配列参照: `Index`, `IndexMut`
- 関数呼び出し: `Fn`, `FnMut`, `FnOnce`

C++では`operator`

## デバッグ出力
- `println!("Display {}", v)`: `Display` 簡易
- `println!("Debug {:?}", v)`: `Debug` 詳細

C++では`operator<<`

## コピー･ムーブ

Rustでは束縛する時にコピーするかムーブするかは, その型に`Copy`トレイトが実装されているかに拠る。

### コピー
```rust:rust
let x : i32 = 1;
let y = x; // i32はCopyトレイトを実装しているのでコピー
println!("{}", x); // OK
```

```cpp
int x = 1;
int y = x;
```

### ムーブ
```rust:rust
let x : &mut i32 = &mut 1; // &mut 32はCopyトレイトを実装していない
let y = x; // ムーブ
//println!("{}", x); // NG
```

```cpp
int x = std::make_unique<int>(x);
auto y = std::move(x);
```

#### 複製
`Copy`が実装されていないくても, `Clone`が実装されていれば`.clone()`で複製できる

```rust:rust
let x = String::from("str"); // StringはCopyを実装していない
let y = x.clone(); // 複製する
println!("{:?}", x); // OK

let x = String::from("str"); // StringはCopyを実装していない
let y = x; // ムーブする xは使えなくなる
//println!("{:?}", x); // NG
```

### デストラクタ
```rust:rust
struct Obj { s: i32 }
impl Drop for Obj {
    fn drop(&mut self) {
        println!("Droped {}.", self.s);
    }
}

{ let _x = Obj { s: "hey" }; }
```

```c++:c++
struct Obj {
    int s;
    Obj(int s):s(s_){}
    ~Obj() {
        std::cout << "Droped " << this.s << std::endl;
    }
}

{ Obj x(1); }
```

### デフォルトオブジェクト
```rust:rust
impl User {
    fn default() -> Self {
        User{name: String::default(), age: u64::default() }
    }
}

let u : User = User::default()
```

```cpp:cpp
// デフォルトコンストラクタ
User u;
```

### Error

### Hash

### Into
```rust:rust
impl Into<u64> for User {
    fn into(self) -> u64 {
        self.age
    }
}
let u : User = User{ name: String::from("Alice"), age: 32 };
let age : u64 = u.into();
```

```c++:c++
struct User {
    /* ... */
    operator int () {
        return this->age;
    }
}
```

### From
```rust:rust
impl From<i32> for User {
    fn from(age : u64) -> Self {
        User { name: String::from("Alice"), age: age }
    }
}

let u : User = User::from(32);
```

```c++:c++
struct User {
    /* ... */
    User(int age) {
        return User{ "Alice", age };
    }
}

User u = 32;
```

### 参照の暗黙の型変換(型強制)
```rust:rust
impl Deref for User {
    fn deref(&self) -> &u64 {
        &self.age
    }
}

let u : User = User{ name: String::from("Alice"), age: 32 };
let refu : &User = &u;
let age : &u64 = &u;
```
`Delef<Target = U>`が実装されている時, 参照は暗黙の型変換が起きる。
参考: [RustのDerefトレイトによる挙動を確認してみた](https://qiita.com/emonuh/items/2607adfc7e7addd2a571)

### AsRef / AsMut

### Borrow / BorrowMut

# データ構造

## 基本データ構造

以下途中

### array
### slice
### tuple
### vec

https://qiita.com/lo48576/items/34887794c146042aebf1

## 無名関数
## メモリ管理

## ポインタ

# その他
## 入出力