プログラミング言語Rustのススメ

# 導入
皆さんこんにちは。趣味で**Rust**を使ってコンパイラを作ってるらいパン粉です。
プログラミング言語**Rust**の良さを雑にあっぴるしていきます。
では、早速cargo run！(このコマンドで**Rust**のプログラムが実行される)
C,C++のコードが出てくるので覚悟してください。

# Rustとは
- Mozillaが応援している言語
- Microsoftも注目している
- 2006年から開発が始まった新しめの言語
- 2016年、2017年、2018年のStack Overflow Developer Surveyで「最も愛されているプログラミング言語」で一位を獲得している
- C/C++と同等の処理速度
- C/C++の代替えを目指している
- 静的に型が付く、コンパイラ言語
- 静的に変数の寿命もわかり、自動でメモリを解放（GCより速い！）
- 関数内部限定での極めて賢い型推論
- C/C++と比べて極めて安全
- オブジェクト指向ではないし関数型言語でもない新たな概念を持つ
- デフォルトでスレッドセーフが保証された変数達
- C++のムーブセマンティクスを言語レベルでサポート
- C++と違い、制約付きのテンプレートがある
- DSL作成可能で健全なマクロ
- タプル、代数的データ型とマッチ式もあります
- 標準でテスト機能が付いている
- 標準でパッケージマネージャーがある

ざっとこんな感じ。
では、早速**Rust**を語っていきます。

# インストールがありえないほど簡単！

基本的にはこのページに従うだけでインストールは終わります。
https://www.rust-lang.org/ja-JP/install.html

Windowsならインストーラを起動するだけ。
MacやLinuxはターミナルにコマンドをコピペしてEnterするだけです。
簡単！

# 爆速でうごくHelloWorld！
**Rust**をインストールすると三つのcommandが使えるようになります。
**Rust**のインストールをする**rustup**。
**Rust**のコンパイラ**rustc**。
パッケージマネージャーの**cargo**。
しかし、実際に触るのは**cargo**だけです。他二つはめったに触りません。

そして、以下のcommandでプロジェクトが生成されます。

```
cargo new プロジェクト名
```
そしてcd コマンドでできたプロジェクトの中に入り、以下のcommandを打ちます。

```
cargo run
```
そうすると画面にHelloWorldが出力されるでしょう。
**Rust**ではプロジェクトを作成すると、`main.rs`というファイルが生成される。
これがいわゆる**Rust**のソースファイルになり、`main.rs`の中身は以下のようになっています。

```rust
fn main() {
    println!("Hello, world!");
}
```
そう！**Rust**ではもはやHelloWorldは書く必要はありません。
わーお

# 公式チュートリアルが日本語に翻訳されている

チュートリアルが日本語であるのはうれしいですね。
すこし、翻訳ががばがばな気がしますが、全然読めます。
https://doc.rust-jp.rs/book-ja/index.html
ほとんど全ての機能が説明されています。
また、**Rust**の日本コミュニティのslackもあります。
**Rust**の達人がたくさんいるので知恵袋やスタックオーバーフローで聞くより良いです。
https://rust-jp.herokuapp.com/

# 所有権&ライフタイムによる、安全で優れた設計の強制
**Rust**は**所有権**と**借用**システムにより、安全で優れた設計を強制します。
このことより、**Rust**を学ぶことは、プログラマーとしての設計能力をいっそう成長させると思います。
ではまず、以下のくそみたいなCのコードを見てみましょう。

```C
#include <stdio.h>

int* hoge(int a, int b){
    int c = a + b;
    return &c;
}

int main(void)
{
    printf("%d", *hoge(8, 2));
    return 0;
}
```
こちらで実行できます。
https://wandbox.org/permlink/nhTU8h2gJnIKJtFQ
`hoge`関数は`8`と`2`を受け取り、足した結果を変数`c`に入れ、そのcの**ポインタ**を返しています。
`main`では変数`c`の**参照**を**デリファレンス**して画面に表示しています。
**デリファレンス**とは**ポインタ**が指している**値**を取得することです。
GCC4.9.3コンパイラでは`10`が画面に表示されました。
しかしローカル変数`c`の寿命は`hoge`内だけなので、`c`の**ポインタ**を`hoge`のスコープ外に渡すのは**未定義動作**です。
**未定義動作**とは、何が起きるかわからないという意味です。
この例では運よく`8+2`が表示されましたが、次はどうでしょうか。

```C
#include <stdio.h>

int* hoge(int a, int b){
    int c = a + b;
    return &c;
}

void fuga(int* d){
    int s = 777;
    printf("%d", *d);
}

int main(void)
{
    fuga(hoge(8, 2));
    return 0;
}
```

こちらで実行できます
https://wandbox.org/permlink/qVQkNsJOlkFQcxje
私が実行したときは画面には`10`ではなく`777`が表示されました。
これは望む結果ではありません。
C言語ではこのような危険なことができますが、**Rust**では**ポインタ**の**寿命**を厳格に管理するため、コンパイル時にエラーしてくれます。
まあ、といっても最近のCコンパイラは賢いのでこの類の**未定義動作**は警告してくれるのですぐに気が付きますが。

一応**Rust**で書くとこんな感じです。これはコンパイルエラーになります。


```rust
fn hoge<'a>(a:i32, b:i32) -> &'a i32{
    let c= a + b;
    return &c;
}

fn main(){
    println!("{}", hoge(8, 2));
}
```
コンパイルエラーの内容は、変数`c`の寿命が短いので持ち出せないよ！といったエラーでした。
**Rust**では**ポインタ**が無効な場所を指さないように、**寿命（ライフタイム）**が有効かどうかを**静的に検査**します。

次により深刻的なケースをC++で紹介します。
これはC++だけでなくC#やJavaにも起こる可能性があります。

### 【例題】
あるところに、二人の若者、`a`と`b`がいた。
ある日、二人は体力勝負をするために、どれだけジャンプできるかを競うことにした。
そのためにカウンターを用意して、ジャンプするたびにカウントして、カウント数が多い方が勝ちとした。

では早速これをC++で実装してみる。
運が悪く、これを実装したC++プログラマは初心者であった。

```c++
//数値をカウントする機械
class Counter{
    int cnt = 0;
public:
    //カウントする
    void count(){
        cnt++;
    }
};

//ジャンプする人
class Jumper{
    Counter* c;
public:
    Jumper(Counter* c){
        this->c = c;
    }
    //ジャンプする。ジャンプしたらカウントする
    void jump(){
        c->count();
    }
    ~Jumper(){
        delete c;
    }
};

int main()
{
    Counter* c = new Counter();
    Jumper a = Jumper(c);
    Jumper b = Jumper(c);//おおっと！間違えて二人に同じカウンターを配布してしまった！
    a.jump();
    b.jump();
}
```
このコードには3つの問題がある。
1つは同じカウンターを二人に渡してしまったので計測ができないことである。
もう1つはわかりずらいが、`Counter`を`Jumper`**デストラクタ**で二回`delete`しているところである。
そして最後はこの、`a`と`b`が非同期で実行される時に起きる。
もし`a`と`b`が非同期で独立して動くプロセスだとして、二人が同時に`jump`したらどうなるだろう？

そう！たったこれだけのコードでもたくさん考慮しないといけないことがある！！
値がどこで書き換わるのか、
その値はもう削除されたのか、
それはスレッドセーフなのか、
これはJavaでもC#でも変わらない。
設計を慎重に行わなければ、可読性の低く、バグを含んだ、状態まみれのクソコードの完成だ！

**Rust**では**所有権システム**がこのようなクソコードを許さない。

まず**Rust**では、**値を書き換えれる責任**は**一つのオブジェクトしか持てない**。
つまり、`a`と`b`に同じカウンターを渡すことは不可能である。
なので値がどこで書き換わるかはあまり意識しなくてよくなる。

さらに**Rust**では**値の削除は全て自動的に行われる**（これについてはあとで）
なので、値の削除について考えることはない。

そして、**値は必ず一か所でしか変更されないため、非同期でも問題なく動く**。

これで**Rust**がいかに安全か分かったと思います。

# null安全
**Rust**の**参照**または**ポインタ**には`null`が**存在しない**。(一応存在はするがunsafe内でのみ使用可能)
なので、間違って`null`の値にアクセスしたりできない。
`null`の代わりに`Option`という構造が用意されています。
以下のCのコードを見てください。

```C
#include <stdio.h>

//intポインタが指す値をカウントする
//nullかもしれないのでちゃんとnullチェックしないとだめ
void count(int* a){
    if(a != NULL)
        *a = *a + 1;
}

int main(){
    int a = 5;
    count(&a);
    printf("%d", a);
    return 0;
}
```

実行はこちら
https://wandbox.org/permlink/xgH6Mu17gGOdvKfL

nullチェック忘れたら大変ですよね。

**Rust**ではこうなります。

```rust
fn count(a: &mut Option<i32>){
    match a.as_mut(){
        Some(x)=> *x += 1,
        None=> ()
    };
}

fn main()
{
    let mut a = Some(5);
    count(&mut a);
    println!("{}", a.unwrap())
}
```
https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=0e0715b56639ec4164a1362895e51616

`Option`は**値がないかもしれないを表す型**で、値を取り出すときに値があるかどうかを**必ずチェック**する必要があります。
これによって、チェックのし忘れは起きません。

コードの解説をします。

まずは`main`関数から。
**Rust**では、変数宣言に`let`が必要です。
`let 変数名`で宣言された変数は値を書き換えることができないため、
今回は`let mut a`として、変数が書き換え可能であることを宣言します。
`mut`は**ミュータブル**の略であり、**変更可能**を意味します。
続いて、`Some(5)`は整数値`5`を`Option`で包んでいます。
変数宣言に型を指定する必要はありません。コンパイラが型を推論してくれます。
続いて`a`をカウントしたいので、`count`関数に渡します。
この時`&mut`修飾子を付けます。これは**変更可能な参照を渡しますよ**とコンパイラに指示しています。
これによってプログラマは、あ、この`count`関数では`a`を書き換えるんだなということが明確にわかります。
あとは`count`内で`Option`の中身である`5`を取り出すために`match`式を用います。ここの詳しい説明はしません。


# エラー処理

**Rust**は関数が失敗したかどうかをキャッチする特別な機構はありません。
**関数の返り値としてエラーかどうかを判別します**。
これにより、例外のcatchミスによる、停止を防げます。
例としてC#の文字列を数値に変換するプログラムを見てみましょう。

```c#
using System;

namespace Wandbox
{
    class Program
    {
        static void Main(string[] args)
        {
          Console.WriteLine(int.Parse("4593"));
          Console.WriteLine(int.Parse("hao123"));//数字じゃないので例外を投げる
        }
    }
}
```
https://wandbox.org/permlink/VFc5pSAzozxN6YxO
このプログラムは`int.Parse`関数を使って文字列を数値に変換してそれを画面に表示するプログラムです。
`int.Parse`は数字に変換できない文字列が与えられると例外を吐くのでしっかりチェックをしないといけないのですが、それを忘れてしまい、プログラムが停止しています。

本来はこうするべきです。

```c#
using System;

namespace Wandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            try{
                Console.WriteLine(int.Parse("4593"));
                Console.WriteLine(int.Parse("hao123"));//数字じゃないので例外を投げる
            }
            catch{
                Console.WriteLine("変換できませんでした");
            }
        }
    }
}
```
https://wandbox.org/permlink/FksyG3lFnxrCH632

では**Rust**での例を見てみましょう。

```rust
fn main()
{
    let a : Result<i32,_> = "4693".parse();
    let b : Result<i32,_> = "hao123".parse();
    match a{
        Ok(x) => println!("{}", x),
        Err(_) => println!("変換に失敗")
    };
    match b{
        Ok(x) => println!("{}", x),
        Err(_) => println!("変換に失敗")
    };

}
```
https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=dca2726190250e98b59d297eb319d2ee
注目すべきは`parse`の結果が`Result`に包まれていることです。
これは**成功か失敗を表す型**です。
**Rust**ではただ`Result`値が返ってくるだけなので、別にプログラムは停止しません。
`Result`値も`Option`同様`match`式で成功か失敗かをチェックしないと値は取り出せません。
少し冗長なコードに見えるかもしれないですが、これはわざとそうしているだけで実はもっとスマートに書けます。(`?`演算子の活用)

# メモリ管理
メモリの管理は一歩間違えれば、足を打ち抜くことになります。
**Rust**ほど素晴らしいメモリ管理はないと思います。
C/C++は早いですがメモリ管理を手動で管理しないといけないので大変です。
スマートポインタも全然スマートじゃありません。
C#/JavaはGCでメモリを自動で管理しますが、メモリ破棄のタイミングは分かりません。
場合によってはバグの発見に遅れるし、デストラクタが使い物にならないので設計がしづらいときがあります。
**Rust**では**コンパイル時に全ての変数の寿命が分かる**ため、**自動でメモリを破棄してくれます**。
GCを使っていないのでC/C++と同等に高速です。素晴らしい！

# テスト
他の言語では単体テストや結合テストを行うのに、テストフレームワークを別途インストールしたりしますが、**Rust**ではそんな面倒なことはしません。
**テストは言語レベルで組み込まれています**。
試しに足し算の関数を作って、それの単体テストを作成してみます。

```rust
fn plus(a:i32,b:i32)->i32{
    a+b
}

#[test]
fn plus_test(){
    assert_eq!(plus(4, 5), 9);
    assert_eq!(plus(100, -1), 99);
    assert_eq!(plus(114000, 514), 114514);
}
```
https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=02dfcf67557dce20f0228aa88180894e

ね、簡単でしょ？
`#[test]`を付けた関数は通常コンパイル時には無視されます。
以下のcommandを打つとRustは`#[test]`が付いた関数を実行しマルチスレッドでテストを開始します。

```rust
cargo test
```

このテストはソースコードのどこにでも書くことができます。

# マクロ

C言語のマクロをご存じでしょうか？
マクロとは、コンパイルする際にコードを指定したルールで置き換えてくれる機能のことです。
**Rust**にもマクロはあります。
**Rust**のマクロはC言語のマクロと比べて、**極めて強力で安全であります**。

## 標準で用意されているマクロの利用
標準で用意されているマクロについてはコチラをご覧いただくか、もっと素晴らしい記事やドキュメントを参照ください。
https://qiita.com/elipmoc101/items/f76a47385b2669ec6db3

## ちょっとしたショートカットにマクロの利用
マクロを使うと文法を拡張できますので、関数分割でも短くできそうにない煩雑な個所をマクロで短く置き換えることができます。

## ドメイン特化言語としてのマクロの利用
**Rust**のマクロを使えば独自の文法でコードを書けるようになります。
これを利用し、可読性と効率を高めることができます。
（やろうと思えば、Haskellのdo構文をある程度は模倣できるようです。）


# 終わりに
**Rust**は本当に最高の言語です。
もしより成長を望むのであれば、この言語を極めるべきだと感じています。
ここに書かれていることは**Rust**の**ほんの一部**でしかないので、公式のチュートリアルを読むことをお勧めします。