Rust をそれなりに書けるようになったところまでの道のりを記録しておく

まだまだ言語のポテンシャルに対して習熟度は高くないと思うけど、比較的小規模なものを Rust で書くことくらいは問題なくできるようになったので、ここまでを振り返っておきたい。

というのも、初めて Rust を勉強し始めたときはあまりの難しさ(というか自分の素養のなさ)により一度挫折しており、二回目に手を付けるときまでそこそこな期間が空いたりしていた。「何をどうやったらこんなものを扱えるようになるのか」というレベルだったときの記憶が強いので、この勉強のプロセスは自分にとっても記録しておきたい体験だったように思う。

別に珍しいことは全く書いてないですが、同じような流れは比較的再現度が高いかもしれません。

The book (The Rust Programming Language) を二周した

数あるチュートリアルや入門ガイドの中でもひときわ素晴らしいシリーズであるといまでも思います。

https://doc.rust-jp.rs/book-ja/
https://doc.rust-jp.rs/book-ja/

そのとき知ればいいことだけを順番に把握していけるようにとてもよく構成が練られていて、他のことが気になったり「あれも知っておかなきゃ」「これも調べておかなきゃ」みたいになりにくいと感じます。つまりただ読んでいくだけでもかなり理解が深まります。読みやすくユーモアのある和訳もポイント高い。

別に二周する必要はないと思うのだけど、自分は一周目は挫折の回だったので、思い出す意味&復習&ちゃんと理解する意味などなど含めてちゃんと二周目に臨んだ。もちろん度々お世話になるガイドであることには違いないので、このあとの手順を踏むなりちょっと書いたりしてみたあとで二周目もちゃんと読み直すというのは大いに価値があると思う。

ひとつひとつの例を写経するべきかどうか、とかは個人のスタイルによると思うのでここでも言及しません。僕は自分の作業を挟むとインプットからフォーカスが外れてしまうので読むだけにする派です。量も多いのでスマホで開いて移動時に読むとかトイレで読むとかちょっとずつやってました。

ちなみに Rust や周辺ツールに関するリファレンスとしてこの同じサイトテーマによるブック形式のガイドが他にもたくさんあって(mdbook という)、一部は未翻訳ですがどれも素晴らしい資料です。一通り読むことをおすすめします。

下記はそれのインデックス。

Learn Rust
Learn Rust
A language empowering everyone to build reliable and efficient software.

Playground 形式の簡易プログラミング問題みたいのをいっぱいやった

これも最近のプログラミング言語やフレームワークあるあるですが、プチ問題形式の学習サイト(公式っぽいやつ)があるのでそれをやりました。

…と思ったのだけど、いくら探しても Rustlings という自分でリポジトリをクローンするなりブラウザ上の VS Code などで問題を解いていくタイプのやつしか見つからない。GPT に聞いてもこれしか言ってくれないし、なくなっちゃったのかな、なんか勘違いしているかな…。

ひとつずつ文法の説明があって、微妙に不足したコードがエディタつきで表示されたりして、ちょっと直して自分で手を動かしていく…ってやつ。

→見つけました!!「Rust ツアー」というやつでした。

https://tourofrust.com/00_ja.html
https://tourofrust.com/00_ja.html

まあこれはいま思うと必須でもない気がするので飛ばしてもいいかも。でも上記の Rustlings というやつは気合いの入り方がすごかったのでちょっと興味あります。やってみるのもありかもですね。

超簡単な CLI ツールをつくった

プログラミング言語の文法だけを知った状態でつくれるミニマムな成果物っておそらく CLI ツールだと思っているので、ネットワーク通信や I/O を必要としないけどなんかちゃんと完成させたいものとしてひとつアプリケーションをつくった。

GitHub - mirumirumi/crock: crock is rock clock 🪨
GitHub - mirumirumi/crock: crock is rock clock 🪨
crock is rock clock 🪨. Contribute to mirumirumi/crock development by creating an account on GitHub.

※このアプリケーションはいまは同じ目的によって Go に書き換えられております…。(その後 Go は全く好きになれず一切勉強はしていない)

そこそこ書ける自信があるならサーバーを書いてみるとかやってもいいと思うんだけど、Rust に関しては(失敗していた経験もあり)本当に簡単な CLI ツールから始めるのが成功だったように感じる。実際コマンドライン引数や環境変数のパースとかは以降も使える知識になるし、文字列操作、文字列フォーマット処理なども良い練習になります。

自分のポリシーとして「どんなに小規模な勉強目的のものであってもちゃんと意味があるものを作り切って完成させてリリースする」というのを絶対のルールにしているのだけど、このあたりたぶんかなり個人差があると思うのでもちろん好きにやれればなんでもいいのだと思います。

Web アプリケーションフレームワーク関係の実践的な本を適当に読んだ

雰囲気はわかってきたということで、もうちょっと実践的な知識を身につけるためにウェブ寄りな本を適当に読みました。手に取った本はいま思うとわりとハズレに近かったものもあった気はするけど、まあ意味はあったかな。

Rust を何用途で使っていきたいかにもよりますが、Web アプリケーションフレームワークが関わるといくらかの派閥抗争に巻き込まれることになります。けれども、本を読む段階でそのフレームワークがどれであるかを気にする必要は全くないと思うし、手に取った本に書いてあったフレームワークを親鳥だとも思わないほうがいいです。ちなみに僕は axum + sqlx を使っている。

それと、このあたりで

  • serde (serde_json)
  • anyhow
  • thiserror

あたりのクレートの存在も知ることになると思います。これくらい揃ってると実際のアプリケーションを書くのに必要なのはあとは

  • chrono
  • regex
  • base64
  • once_cell

くらいだろうか。非同期系をちゃんと理解するタイミングになかなか恵まれないのがネックかなあ(これは自分もダメだったと思う)。

自分がもともと書いていたサーバー側のアプリケーションを Rust に書き換えた

これも勉強目的で普段からよくやっているのだけど、個人で運用しているサービスなりツールなりを全部書き直したりします。Rust への書き直しは 3 つ分やりました。

自分はサーバーは全部 AWS で書くので、AWS SDK の使い方とかに慣れる意味も含まれてます。実際には Lambda で Rust を使いたかったのでそのあたりの練習にもすごい時間を使ったけど、この辺は単なる趣味なのでちょっと本題からは逸れます。

サーバーはどれも REST API ですが、前述の axum を使ったり使わなかったりした。Rust は http や hyper、もしくは tower シリーズなどが驚くほど高機能で高品質なので、ぶっちゃけ小規模な API ならフレームワークとかなくても全然いけました。この辺で格闘した成果が lambda_http や axum のミドルウェア系を使うときにもそのまま活かされるのでよい経験だったと思えています。

あと、このタイミングで初めて Rust の性能の高さを実感した。動きが速いのはもちろんだし、Lambda で動かしてもコールドスタートが爆速なのには笑いました。

ちょっと複雑で実用的な CLI ツールをつくった

だいたい勘どころが掴めてきたなというタイミングで、そこそこに複雑な CLI アプリケーションを作ってみました。サーバーだと何をどうやろうが同じような感じになってしまうし、やっぱり Rust みたいな言語を使って複雑なソフトウェアを楽しく書くにはライブラリや CLI アプリケーションだよなと。実際これまで書いた中で一番楽しかったかもしれない!

GitHub - mirumirumi/ro-soku: Retrieve OHLCV ro-soku (means candle in Japanese) from any exchange🕯️
GitHub - mirumirumi/ro-soku: Retrieve OHLCV ro-soku (means candle in Japanese) from any exchange🕯️
Retrieve OHLCV ro-soku (means candle in Japanese) from any exchange🕯️ - GitHub - mirumirumi/ro-soku: Retrieve OHLCV ro-soku (means candle in Japanese) from any exchange🕯️

階層ごとに抽象化をしていく作業、そのそれぞれに Rust 固有の機能が美しくかつ過不足なくハマっていくところ、コンパイルが通ると実行時エラーを見ることがほぼないところ、そのうえテストも同じファイルに見通しよくすぐに書けるところ、すべてがよかった。これが人気の理由なのかと実感した。

あと、この段階に来るまで困っていたのがクレートのリファレンスの見方について。

https://docs.rs
https://docs.rs

各クレートのドキュメントは基本的にこのサイト内で見るのが通例で、リポジトリの README には何も書いてなかったりサマリー用の説明しかなかったりします(ただしこれは Rust のソースコード内からそのままドキュメントを生成できる類まれな機能によるものなのでもちろん否定の対象ではない)。

ところがこのドキュメントから全体の使い方や必要なメソッドを探したりするのが何度やってもうまくできるようになれず、かなり四苦八苦した。

いまはなぜ困らなくなったのか頑張って考察をしてみるとするなら、「ドキュメントの見方うんぬんより Rust 側の理解度が上がることのほうが重要だった」とかでしょうか。

たぶん「こういう使い方をしたいときは構造体をまずつくってからだな」とか「モジュール直下にメソッドがありそうだな」とかなんとなくわかるようになってくる…みたいな。あとは検索機能が便利で優秀なので積極的に使うこともおすすめしたいです。

それと忘れがちですが、README と docs.rs のリファレンスを見つつ、豊富な examples も併せて参照すると理解が深まります。この examples もテスト対象で、常に最新のコードでコンパイルが通ることが保証されているので信頼度が高いです。

サーバーレス、コンテナ、ジョブスクリプトなど、一通りの形態で新規に書くようにした

あとはもう新しく何かつくるときになるべく Rust を採用するようにしただけ。ビッグでモノリシックなチームプロジェクトで自分だけが牽引して選べるほどにはまだなっていないけど、十分手札には加わったかなと思う。

サーバーレスは前述の通り Lambda の動かし方やテンプレートはつくれているし、コンテナはまあ特にやることない、バッチみたいのは気軽にスポットで Rust を採用できるいいチャンス。

だいたいどんなシーンでも Rust で困ることはないし、よく言われるような too much 感もあまり感じていないです。unwrap() を積極的に使うとかライフタイムは(特に構造体には)入れるのは避けようなど、 Rust の硬さをほぼ殺さないまま便利さだけを上げられるポテンシャルもあるので。実際上級者の話を直接聞いた感じ、例えばライフタイムはあまり書かないようにするというスタイルも普通に取ってそうだった。

フロントエンドは… まあ色々工夫をこらしたフレームワークは出てきてはいますが、さすがにこれが Rust に染まるのはしばらく期待はできなそうですね。あとデスクトップアプリケーション用の Tauri については結局中身がほとんど JS なのが残念だった。

というわけで、みなさんも Rust いかがですか!