前置き
これはRustを学びたいけどどうやって勉強しようかという人向けの記事です。
自分の経験からここ先に読んどきゃよかったとか、ここ読んどけばもっと楽だったとかそんなのをいろいろまとめてあります。もう一度Rustを学び直すならどうするかなー、と考えながら書きました。なお大半が英語の資料です。
英語か・・・と思った方はyukiさんのRust を始めるための資料集もどうぞ。
対象はRuby、Pythonなどの高レベル言語をすでに習得してる人。
前準備
Rustの主な特徴を知っておきましょう。Rustは他の言語にない考え方や特徴が多いので先に知っておくと良いです。とりあえずinto_rust() : screencasts for learning Rustを全部見ましょう
基礎知識の習得
The Bookと呼ばれる公式の入門書があります。まずこれを読みましょう。日本語訳もありますが英語版のほうが版が新しいです。
加えて実践Rust入門も手元において読みましょう。The Bookは詳細な説明が多いですがたまに冗長に感じることがあります。実践Rustは日本語ですし、図が多く簡潔にかかれているので両方使うと理解が深まります。
とりあえずこの二冊を中心にいろいろ勉強していくと良いです。
その他の参考書籍
これらに加えて、Dhghomon/easy_rustもおすすめです。
上であげた二冊でよくわからないところはこの本を参照してみてください。簡単な言葉とわかりやすい例で説明されていて参考になります。
ぶっちゃけこの本からいきなり読むのも良いかもしれません。それぞれのトピックは短めで、難しい概念(ライフタイムなど)の説明はこの本のほうがある程度割り切ってる気がします。かえってわかりやすいかもしれません。
The Bookと実践Rustでカバーしきれないところ
ライフタイム
結構な鬼門です。所有関係、マクロ、ライフタイムはどこかのアンケートでも学習者がかなり苦労している項目だとかありました。The Bookのライフタイムの項目を読んでもいまいちよくわからない場合は以下の2つが参考になります
RustnomiconのLifetimeの章は更に突っ込んだ内容が書いてあります。
抽象的な知識より実例がたくさん見たい人はLearning Rust With Entirely Too Many Linked Listsを読みましょう、LinkedListをRustで実装してくチュートリアルです。ライフタイムだけでなくBox、Rc、Arcなどの実用例も豊富です。
エラー処理
The Bookにはエラー処理の章がありますがちょっと足りません。
実際ここだけ読んでコードを書き始めたらそこらじゅうunwrap()
だらけになりました。
(ドキュメントでもunwrap()
はあまりつかってくれるなとあります)
?
オペレーターを使ったほうがいいのはわかるんだけどどうすりゃいいの?
Resultを返すってどうすんの?
と思ったら、Error Handling in Rustを読みましょう。
(この記事は以前The Bookのエラー処理の章に掲載されていたようです、何が会ったか知らないが最新版では消えています。日付は古い記事ですが、Rust2018に合わせて内容が更新されています。)
BoxとかArcとかRcってなにさ?
The Bookや公式ドキュメントを読むと、BoxはリカーシブなStructを定義するときに使って、とかRcだと所有者を増やすことができて、とかいろいろ説明があります。いまいちよくわかりません、実例がほしい。
Learning Rust With Entirely Too Many Linked Listsが実例を交えて詳しく書いてあります。
マクロ
ここも鬼門。
まずはκeenさんのマクロクラブ Rust支部が参考になりました。
マクロで記述量を減らして可読性を高める話も実例が詳細で大変わかりやすいです。
最近追加されたProcMacroについては私の記事で恐縮ですがRust ProcMacro 101をどうぞ。
実例がたくさん見たいという人は、
やちょっと難しいですが
が良いです。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つエラーが出てもものすごい間違いをしているように見えます。
例えば、
fn hi(name: String) -> i64 {
format!("Hi {n}!!", n = name)
}
fn main() {
println!("{}", hi("Joe".to_string()))
}
とリターンタイプをわざと間違えて書きます。そうすると・・・
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は公式ドキュメントがとても良く書けてます
Rustは公式ドキュメントが簡潔に、かつわかりやすく書かれています。
たいてい説明に加えて、
let a = [1, 2, 3];
let doubled: Vec<i32> = a.iter()
.map(|&x| x * 2)
.collect();
assert_eq!(vec![2, 4, 6], doubled);
のようにテストコードまで載っていることがしばしば。検索もとてもスピーディです。
シンタックスを忘れてしまったらチートシートも参照してみてください。
stackoverflowではカービィのアイコンを探す
それでもわからないときはstackoverflow。いい記事もあるのですが、全部が全部いい記事ではないですし、たまに動かないコードに出くわすことも。ちゃんとした記事かどうか見分けるには・・・?
とりあえずShepmasterさんのカービィのアイコンを探しましょう。stackoverflow上でものすごくアクティブにRustの質問を解決してる方です。経歴を見ると、Rust専門のコンサルをやっているようです。
それでもわからん、誰か教えて!
rust-jpというslackチャンネルがあります。
おまけ
未読だけど面白そうなもの