「The Rust Programming Language」でRustを学ぶ その04 Enum,match,if-let,パッケージなど(7章まで)

2025-08-26 10:13:44

The Rust Programming Language 日本語版 - The Rust Programming Language 日本語版

の、今回は6章「Enumとパターンマッチング」、7章「パッケージ」

ソースは下記のipaddrディレクトリと、restaurantディレクトリ
ryotakato/rust_the_book_src

Enumとパターンマッチングのほうは、if let構文が面白かった。
Lispとかやったことあるので、letが束縛っていうのは全然違和感ないので、
if let構文でてきても、まあそうだよねーって感じだけど、
Rustの変数のシャドーイングも相まって、if letの左辺と右辺に書く変数にいつもちょっと混乱する。

      let ip_addr = (独自のenum: IpAddrを包んだOption型を返すようにする)
      if let Some(ip_addr) = ip_addr {
          println!("{}", ip_addr);
      }

みたいな処理があったときに、if let構文のip_addrって何を指しているっけ?って。
正解は、左辺のip_addrがenum:IpAddrで、右辺が、Option。 if let のスコープの中では、左辺の変数が使われる。 別の変数つかえばいいじゃないって言われそうだけど、 シャドーイング便利なんだよなー。

まあ、if letもシャドーイングも慣れなんだろうけど。

さて、パッケージなどプロジェクトの構成要素について。

  • パッケージ
    • cargo new して作るやつ Cargo.tomlを持つ
  • クレート
    • パッケージに1個はないといけない。
    • 名前空間の機能も持っている。
    • Rustが一度にコンパイルするときの翻訳単位(つまりクレート内のファイルは一度でコンパイルされる)。
    • 内包するモジュールのルートである
    • バイナリクレート: パッケージにいくつでも可
    • ライブラリクレート: パッケージには 0or1 個しか作れない
  • モジュール
    • クレート内をさらに名前空間わけする
    • アクセス制御可能。
    • ファイル単位で分けるのがよくある使い方?
    • 参照はcrate::で始まる絶対パスと、相対パスがある。(相対パスしかほぼ使わない?)

なお、ファイル的には下記な感じ

  • src/main.rsは、デフォルトバイナリクレート(パッケージ名と同名)のエントリポイント
  • src/bin配下に置いたファイルは別バイナリとなる(ファイル置いただけバイナリも作られる)
  • src/lib.rsは、デフォルトライブラリクレート(パッケージ名と同名)のエントリポイント

クレートがコンパイルの単位というのが大きくて、
C言語やC++のファイル単位でコンパイルするのとは違う
(これらの言語は、ファイル単位のせいで、includeによるソース埋め込みが必要になっている)

モジュールを読み込むときのuseの慣例は、

  • 関数を読み込むときは、useで関数を含むモジュールを読み込むつつ、関数を直接含むモジュール名をつけて呼び出す (例: use std::fmt; と読み込んで、fmt::formatと使うとか)
  • 構造体やenumは、useでその構造体やEnumまで読み込みつつ、構造体やEnumを直接呼び出す(例: use std::fmt::Formatter と読み込んで、Formatterと使うとか)
  • ただし、std::fmt::Resultと、std::io::Resultで、名前がぶつかる場合はモジュール名つける (fmt::Result, io::Result)か、asでエイリアスつける
    っていう感じ。
    まあ、そう不思議なことはない。

ちなみに、今回restaurantパッケージは初めてlibで作ってみたが、
Rustの、コンパイルエラーにすることで実行時エラーを減らすという思想の恩恵を受けることが結構できた。
どういうことかというと、
ライブラリを開発しているときに、この書き方できるのかな、ってちょっと疑問に思ったときも、
cargo buildでとりあえずコンパイル走らせれば大丈夫かどうか確認してくれる。
実行するためのmain.rsを書かなくても、ある程度動くものが作れているなって実感があるので、思ったより生産性が高い気がする。
まあ、他の言語もコンパイル言語はわりとチェックしてくれる気がするが、なんか安心感が違うなー。

参考
[Rust] クレート分けのベストプラクティス

とりあえず、今日はそんなところ。




Comments

There are currently no comments on this article, be the first to add one below

Add a Comment

Note that I may remove comments for any reason, so try to be civil. If you are looking for a response to your comment, either leave your email address or check back on this page periodically.