モジュールを複数のファイルに分割する
この章のすべての例において、今までのところ、複数のモジュールを一つのファイルに定義していました。 モジュールが大きくなる時、コードを読み進めやすくするため、それらの定義を別のファイルへ移動させたくなるかもしれません。
例えば、Listing 7-17 のコードからはじめましょう。クレートルートのファイルをListing 7-21 のコードを持つように変更して、front_of_house
モジュールをそれ専用のファイルsrc/front_of_house.rs
に動かしましょう。
今回、クレートルートファイルはsrc/lib.rs
ですが、この手続きはクレートルートファイルがsrc/main.rs
であるバイナリクレートでもうまく行きます。
ファイル名: src/lib.rs
mod front_of_house;
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}
そして、 Listing 7-22 のように、src/front_of_house.rs にはfront_of_house
モジュールの中身の定義を与えます。
ファイル名: src/front_of_house.rs
pub mod hosting {
pub fn add_to_waitlist() {}
}
mod front_of_house
の後にブロックではなくセミコロンを使うと、Rustにモジュールの中身をモジュールと同じ名前をした別のファイルから読み込むように命令します。
私達の例で、つづけてhosting
モジュールをそれ専用のファイルに抽出するには、src/front_of_house.rs
がhosting
モジュールの宣言のみを含むように変更します:
ファイル名: src/front_of_house.rs
pub mod hosting;
さらにsrc/front_of_house ディレクトリとsrc/front_of_house/hosting.rs ファイルを作って、hosting
モジュール内でなされていた定義を持つようにします。
ファイル名: src/front_of_house/hosting.rs
#![allow(unused)] fn main() { pub fn add_to_waitlist() {} }
定義は別のファイルにあるにもかかわらず、モジュールツリーは同じままであり、eat_at_restaurant
内での関数呼び出しもなんの変更もなくうまく行きます。
このテクニックのおかげで、モジュールが大きくなってきた段階で新しいファイルへ動かす、ということができます。
src/lib.rs におけるpub use crate::front_of_house::hosting
という文も変わっていないし、use
はどのファイルがクレートの一部としてコンパイルされるかになんの影響も与えないということに注意してください。
mod
キーワードがモジュールを宣言したなら、Rustはそのモジュールに挿入するためのコードを求めて、モジュールと同じ名前のファイルの中を探すというわけです。
まとめ
Rustでは、パッケージを複数のクレートに、そしてクレートを複数のモジュールに分割して、あるモジュールで定義された要素を他のモジュールから参照することができます。
これは絶対パスか相対パスを指定することで行なえます。
これらのパスはuse
文でスコープに持ち込むことができ、こうすると、そのスコープで要素を複数回使う時に、より短いパスで済むようになります。
モジュールのコードは標準では非公開ですが、pub
キーワードを追加することで定義を公開することができます。
次の章では、きちんと整理されたあなたのコードで使うことができる、標準ライブラリのいくつかのコレクションデータ構造を見ていきます。