モジュールを定義して、スコープとプライバシーを制御する
この節では、モジュールと、その他のモジュールシステムの要素
――すなわち、要素に名前をつけるための パス 、パスをスコープに持ち込むuse
キーワード、要素を公開するpub
キーワード――
について学びます。
また、as
キーワード、外部パッケージ、glob演算子についても話します。
とりあえず、今はモジュールに集中しましょう!
モジュール はクレート内のコードをグループ化し、可読性と再利用性を上げるのに役に立ちます。 モジュールは要素の プライバシー も制御できます。プライバシーとは、要素がコードの外側で使える (公開 public) のか、内部の実装の詳細であり外部では使えない (非公開 private) のかです。
例えば、レストランの機能を提供するライブラリクレートを書いてみましょう。 実際にレストランを実装することではなく、コードの関係性に注目したいので、関数にシグネチャをつけますが中身は空白のままにします。
レストラン業界では、レストランの一部を 接客部門 (front of house) といい、その他を 後方部門 (back of house) といいます。 接客部門とはお客さんがいるところです。接客係がお客様を席に案内し、給仕係が注文と支払いを受け付け、バーテンダーが飲み物を作ります。 後方部門とはシェフや料理人がキッチンで働き、皿洗い係が食器を片付け、マネージャが管理業務をする場所です。
私達のクレートを現実のレストランと同じような構造にするために、関数をネストしたモジュールにまとめましょう。
restaurant
という名前の新しいライブラリをcargo new --lib restaurant
と実行することで作成し、Listing 7-1 のコードを src/lib.rs に書き込み、モジュールと関数のシグネチャを定義してください。
ファイル名: src/lib.rs
mod front_of_house { mod hosting { fn add_to_waitlist() {} fn seat_at_table() {} } mod serving { fn take_order() {} fn serve_order() {} fn take_payment() {} } } fn main() {}
モジュールは、mod
キーワードを書き、次にモジュールの名前(今回の場合、front_of_house
)を指定することで定義されます。
モジュールの中には、今回だとhosting
とserving
のように、他のモジュールをおくこともできます。
モジュールにはその他の要素の定義も置くことができます。例えば、構造体、enum、定数、トレイト、そして(Listing 7-1のように)関数です。
モジュールを使うことで、関連する定義を一つにまとめ、関連する理由を名前で示せます。 このコードを使うプログラマーは、定義を全部読むことなく、グループ単位でコードを読み進められるので、欲しい定義を見つけ出すのが簡単になるでしょう。 このコードに新しい機能を付け加えるプログラマーは、プログラムのまとまりを保つために、どこにその機能のコードを置けば良いのかがわかるでしょう。
以前、 src/main.rs と src/lib.rs はクレートルートと呼ばれていると言いました。
この名前のわけは、 モジュールツリー と呼ばれるクレートのモジュール構造の根っこ (ルート)にこれら2つのファイルの中身がcrate
というモジュールを形成するからです。
Listing 7-2は、Listing 7-1の構造のモジュールツリーを示しています。
crate
└── front_of_house
├── hosting
│ ├── add_to_waitlist
│ └── seat_at_table
└── serving
├── take_order
├── serve_order
└── take_payment
このツリーを見ると、どのモジュールがどのモジュールの中にネストしているのかがわかります(例えば、hosting
はfront_of_house
の中にネストしています)。
また、いくつかのモジュールはお互いに 兄弟 の関係にある、つまり、同じモジュール内で定義されていることもわかります(例えばhosting
とserving
はfront_of_house
で定義されています)。
他にも、家族関係の比喩を使って、モジュールAがモジュールBの中に入っている時、AはBの 子 であるといい、BはAの 親 であるといいます。
モジュールツリー全体が、暗黙のうちに作られたcrate
というモジュールの下にあることにも注目してください。
モジュールツリーを見ていると、コンピュータのファイルシステムのディレクトリツリーを思い出すかもしれません。その喩えはとても適切です! ファイルシステムのディレクトリのように、モジュールはコードをまとめるのに使われるのです。 そしてディレクトリからファイルを見つけるように、目的のモジュールを見つけ出す方法が必要になります。