Rust を導入してみた話

<!-- Rust を導入してみた話 -->

# Rust とは

Rust は Mozilla が支援しているプログラミング言語です。特徴は、

- GC を使わないメモリ管理
- ゼロコスト抽象化
- 高パフォーマンス

などで、C++ に比較的近い設計思想を持っています。

# 導入したきっかけ

C/C++ による開発が求められる高パフォーマンスなプログラムをもっとモダンに開発できないかということで新規開発で導入してみました。まだ それほど Rust 製のプロダクトを開発した経験がないため C/C++ と比較してどの程度速いのかは未知数なところはありますが、[The Computer Language Benchmarks Game] という各プログラミング言語のベンチマークを比較するサイトでは [Rust vs C] で C に匹敵するほどの結果になっており期待ができそうです。

# 開発環境

- Linux
- Rust 1.32.0 (Rust 2018 Edition)

# 使用したツール

| ツール             | 説明             |
|--------------------|------------------|
| Visual Studio Code | IDE として使用   |
| Rust (rls)         | VSCode 拡張機能  |
| CodeLLDB           | VSCode 拡張機能  |
| LLDB               | デバッガ         |
| Rustfmt            | コード整形ツール |
| Clippy             | Linter           |

# 作成したもの

CLI ツールを作成しました。実装にはもともと C++ で書かれた API を使用する必要があったため一旦 C++ のコードを Rust のコードに変換する必要がありました。

# 使用したライブラリ

| ライブラリ    | 説明                         |
|---------------|------------------------------|
| [bindgen]     | C/C++ -> Rust 変換ツール       |
| [structopt]   | コマンドラインパーサ         |
| [env_logger]  | ロギングライブラリ           |
| [failure]     | エラーハンドリングライブラリ |
| [exitfailure] | エラーハンドリングライブラリ |
| [indicatif]   | 進捗バー表示                 |

ライブラリは Rust で CLI を作成するときの公式手引書である [Command Line Book] を参考に採用しました。`structopt` によるヘルプメッセージはカラー表示できるためリッチなインターフェースにすることができました。`bindgen` は C/C++ のコードを Rust のコードに変換してくれるツールですが、使っていて感動したのは自動生成されたコードの中にちゃんと単体テストのコードも生成されている点です。

# 使用感

## 安全かつ高パフォーマンス

Rust のライフタイムやムーブセマンティクスといった概念があるおかげで安全で高パフォーマンスな開発が実現できました。Rust は型やメモリ管理に関してかなり厳しいルールを採用しています。そのためコンパイルを通すまでが厳しい道程で、それ自体がプログラムのデバッグであるかのような感覚でした。

## 明瞭なエラーメッセージ

エラーメッセージがかなり分かりやすいです。メッセージはカラーで表示され、どの構文に問題があるかを波線を引いて教えてくれます。またエラーの詳細を案内するコマンドやリファレンスがあるので、エラーの原因が分からずにハマってしまうということがありませんでした。

```shell:エラーの詳細を表示
$ rustc --explain [index]
```

- [Rust Compiler Error Index] - エラーメッセージのリファレンス

各エラーはちゃんとインデックス管理されているので、とても分かりやすいです。

## C/C++ のエコシステムが使える

デバッガは GDB/LLDB が使用でき、メモリデバッガには [Valgrind] が使えます。C/C++ 開発者にとっては使い慣れたツールなので有り難い点だと思います。ただ今の所 Valgrind にお世話になるほど困難な状況になったことはありません。

# 苦労した点

サードパーティ製ライブラリを導入すると、ソースコードからコンパイルが実行されるため、すべてのライブラリのコンパイルが終了するまでにかなり時間がかかりました。コンパイル時間を削減するために、コンパイルキャッシュツールである [sccache] を導入したところ時間が大幅に削減されました。

インストールは

```shell
$ cargo install sccache
```

で、使用するには

```shell
$ RUSTC_WRAPPER=sccache cargo build
```

と環境変数 `RUSTC_WRAPPER` を設定するだけで簡単にキャッシュすることができます。

# 導入に向けての注意点

Rust はまだ誕生して間もない言語なので、導入を検討する際にはサードパーティ製のライブラリがどの程度安定して使用できるかは把握しておいたほうが良さそうです。また知識を持った人が少ないと属人化が起こってしまうので、メンバへの教育もちゃんと行っていく必要があります。

# まとめ

従来 C/C++ が必要とされていたシーンで Rust を導入すると効果的ではないかと考えています。アルゴリズム開発のような高パフォーマンスが求められる開発で使用するとメリットが大きそうです。キラーアプリとなるライブラリやフレームワークが登場すれば利用が加速すると思うので今後もキャッチアップは続けていきたいと思います。

# 参考

- [Rust 公式]
- [Command Line Book]

[bindgen]: https://github.com/rust-lang/rust-bindgen
[structopt]: https://crates.io/crates/structopt
[env_logger]: https://crates.io/crates/env_logger
[failure]: https://crates.io/crates/failure
[exitfailure]: https://crates.io/crates/exitfailure
[indicatif]: https://crates.io/crates/indicatif
[sccache]: https://crates.io/crates/sccache
[Rust 公式]: https://www.rust-lang.org/
[Command Line Book]: https://rust-lang-nursery.github.io/cli-wg/
[Rust Compiler Error Index]: https://doc.rust-lang.org/error-index.html
[Valgrind]: http://valgrind.org/
[The Computer Language Benchmarks Game]: https://benchmarksgame-team.pages.debian.net/benchmarksgame/
[Rust vs C]: https://benchmarksgame-team.pages.debian.net/benchmarksgame/faster/rust.html

# 備考
※2019/02/18　テキストを修正しました。