Rustはこうやって勉強するといいんじゃないか、という一例

# 前置き

これはRustを学びたいけどどうやって勉強しようかという人向けの記事です。

自分の経験からここ先に読んどきゃよかったとか、ここ読んどけばもっと楽だったとかそんなのをいろいろまとめてあります。もう一度Rustを学び直すならどうするかなー、と考えながら書きました。なお大半が英語の資料です。

英語か・・・と思った方は[yuki](https://twitter.com/helloyuki_)さんの[Rust を始めるための資料集](https://blog-dry.com/entry/2021/01/23/141936)もどうぞ。

対象はRuby、Pythonなどの高レベル言語をすでに習得してる人。

# 前準備
Rustの主な特徴を知っておきましょう。Rustは他の言語にない考え方や特徴が多いので先に知っておくと良いです。とりあえず[into_rust() : screencasts for learning Rust](http://intorust.com/)を全部見ましょう

# 基礎知識の習得

[The Book](https://doc.rust-lang.org/book/title-page.html)と呼ばれる公式の入門書があります。まずこれを読みましょう。日本語訳もありますが英語版のほうが版が新しいです。

加えて[実践Rust入門](https://gihyo.jp/book/2019/978-4-297-10559-4)も手元において読みましょう。The Bookは詳細な説明が多いですがたまに冗長に感じることがあります。実践Rustは日本語ですし、図が多く簡潔にかかれているので両方使うと理解が深まります。

とりあえずこの二冊を中心にいろいろ勉強していくと良いです。

## その他の参考書籍

これらに加えて、[Dhghomon/easy_rust](https://dhghomon.github.io/easy_rust/Chapter_1.html)もおすすめです。

上であげた二冊でよくわからないところはこの本を参照してみてください。簡単な言葉とわかりやすい例で説明されていて参考になります。

ぶっちゃけこの本からいきなり読むのも良いかもしれません。それぞれのトピックは短めで、難しい概念(ライフタイムなど)の説明はこの本のほうがある程度割り切ってる気がします。かえってわかりやすいかもしれません。

# The Bookと実践Rustでカバーしきれないところ

## ライフタイム

結構な鬼門です。所有関係、マクロ、ライフタイムはどこかのアンケートでも学習者がかなり苦労している項目だとかありました。The Bookのライフタイムの項目を読んでもいまいちよくわからない場合は以下の2つが参考になります

[RustnomiconのLifetimeの章](https://doc.rust-lang.org/nomicon/lifetimes.html)は更に突っ込んだ内容が書いてあります。

抽象的な知識より実例がたくさん見たい人は[Learning Rust With Entirely Too Many Linked Lists](https://rust-unofficial.github.io/too-many-lists/)を読みましょう、LinkedListをRustで実装してくチュートリアルです。ライフタイムだけでなくBox、Rc、Arcなどの実用例も豊富です。

## エラー処理

The Bookにはエラー処理の章がありますがちょっと足りません。

実際ここだけ読んでコードを書き始めたらそこらじゅう`unwrap()`だらけになりました。
(ドキュメントでも`unwrap()`は[あまりつかってくれるな](https://doc.rust-lang.org/std/option/enum.Option.html#method.unwrap)とあります)

`?`オペレーターを使ったほうがいいのはわかるんだけどどうすりゃいいの?

Resultを返すってどうすんの?

と思ったら、[Error Handling in Rust](https://blog.burntsushi.net/rust-error-handling/)を読みましょう。

(この記事は以前The Bookのエラー処理の章に掲載されていたようです、何が会ったか知らないが最新版では消えています。日付は古い記事ですが、Rust2018に合わせて内容が更新されています。)


## BoxとかArcとかRcってなにさ?

The Bookや公式ドキュメントを読むと、BoxはリカーシブなStructを定義するときに使って、とかRcだと所有者を増やすことができて、とかいろいろ説明があります。いまいちよくわかりません、実例がほしい。

[Learning Rust With Entirely Too Many Linked Lists](https://rust-unofficial.github.io/too-many-lists/)が実例を交えて詳しく書いてあります。

## マクロ

ここも鬼門。

まずはκeenさんの[マクロクラブ Rust支部](https://keens.github.io/blog/2018/02/17/makurokurabu_rustshibu/)が参考になりました。

[マクロで記述量を減らして可読性を高める話](https://qiita.com/statiolake/items/e7a96fb8b99f31902faa)も実例が詳細で大変わかりやすいです。

最近追加されたProcMacroについては私の記事で恐縮ですが[Rust ProcMacro 101](https://dev.to/takaakifuruse/rust-macro-101-52dg)をどうぞ。

実例がたくさん見たいという人は、

https://github.com/azriel91/proc_macro_rules

やちょっと難しいですが

https://github.com/dtolnay/proc-macro-workshop

が良いです。proc-macro-workshopは問題の答えがありませんが、

https://github.com/ELD/proc-macro-workshop
https://github.com/jonhoo/proc-macro-workshop
https://github.com/gobanos/proc-macro-workshop

のようにフォーク先を見ると答えを書いてる人がたくさんいます。

## コンパイルエラーに慣れる

Rustを書いてるとコンパイル時のエラーが多くでるので心が折れる、という声もあります。
それはRustのエラーメッセージがとても細かいからかもしれません。
なので、1つエラーが出てもものすごい間違いをしているように見えます。

例えば、

```rust
fn hi(name: String) -> i64 {
    format!("Hi {n}!!", n = name)
}

fn main() {
    println!("{}", hi("Joe".to_string()))
}
```
とリターンタイプをわざと間違えて書きます。そうすると・・・

```rust
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
 --> src/main.rs:2:5
  |
1 | fn hi(name: String) -> i64 {
  |                        --- expected `i64` because of return type
2 |     format!("Hi {n}!!", n = name)
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i64`, found struct `std::string::String`
  |
  = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.
```

どっさり。
量だけ見るとものすごい怒りようですね。
でもよく見ると「i64を返すべきなのに、Stringを返してます」と言っています。
加えてどこで合致しない値を返してるかまで指摘しています。
とても親切です。



# 疑問の解決

いかんいかんとわかってても、どうしてもstackoverflow-drivenな開発になっちゃいますよね。

すべてのドキュメントがよくかけてるわけではありません。

実行結果だけ知りたいのに、延々と抽象的な説明が書いてあるだけ、とか、ソースコードがいきなり貼られてるだけ、とか、実行結果みてもいまいちよくわからん、とか・・・


## Rustは[公式ドキュメント](https://doc.rust-lang.org/std/index.html)がとても良く書けてます

Rustは公式ドキュメントが簡潔に、かつわかりやすく書かれています。
たいてい説明に加えて、

```rust
let a = [1, 2, 3];

let doubled: Vec<i32> = a.iter()
                         .map(|&x| x * 2)
                         .collect();

assert_eq!(vec![2, 4, 6], doubled);
```
のようにテストコードまで載っていることがしばしば。検索もとてもスピーディです。

シンタックスを忘れてしまったら[チートシート](https://cheats.rs/)も参照してみてください。



## stackoverflowではカービィのアイコンを探す

それでもわからないときはstackoverflow。いい記事もあるのですが、全部が全部いい記事ではないですし、たまに動かないコードに出くわすことも。ちゃんとした記事かどうか見分けるには・・・?

とりあえず[Shepmasterさん](https://stackoverflow.com/users/155423/shepmaster?tab=profile)のカービィのアイコンを探しましょう。stackoverflow上でものすごくアクティブにRustの質問を解決してる方です。経歴を見ると、Rust専門のコンサルをやっているようです。


## それでもわからん、誰か教えて!

[rust-jp](https://twitter.com/dorayaki_kun/status/1073884752929710080?lang=en)というslackチャンネルがあります。

# おまけ

未読だけど面白そうなもの

- [Writing an OS in Rust](https://os.phil-opp.com/)
- [Learn Rust the Dangerous Way](http://cliffle.com/p/dangerust/)
- [Rustの `Arc` を読む](https://qiita.com/qnighy/items/4bbbb20e71cf4ae527b9)
- [Implementing ArrayVec Using Const Generics](http://adventures.michaelfbryan.com/posts/const-arrayvec/)
- [synとかanyhowとかthiserrorの作者のdtolnayさんの書いた特殊な用法のコード事例集](https://github.com/dtolnay/case-studies)