📌 モジュールを定義
モジュールの定義は mod
を使います.モジュールの本体は {}
で囲みます.モジュールの中にモジュールを定義できます.
mod M1 {
mod M2 {
mod M3 {
fn hoge() {}
}
}
mod M4 {
fn foo() {}
fn bar() {}
}
}
モジュールは同じモジュール内に対してだけ公開された状態になります.そこで,外部のモジュールに対しても公開するには pub
を使います. pub
はモジュール,関数,構造体などに1つずつ設定できます.
pub mod M1 {
pub mod M2 {
pub mod M3 {
pub fn hoge() {}
}
}
}
📌 パス
モジュールを利用するには パス が必要です.モジュールの起点はクレートルートで,パスは crate
になります.前のコードが src/main.rs
に含まれていた場合,それぞれのパスは次のようになります.
crate
└─ M1
├─ M2
│ └─ M3
│ └── hoge
└─ M4
├── foo
└── bar
パスの指定には2種類あります.絶対パスと相対パスです.絶対パスはクレートルートを表す crate
,または外部パッケージおよび標準ライブラリの場合はパッケージ名から指定できます.相対パスの場合は self
, または super
を使います. self
は現在のモジュールから, super
は親のモジュールからの指定になります.パスの区切りは ::
を使います.ちなみに self::
は省略できます.
crate::M1::M2::M3::hoge
📌 モジュールの利用
モジュールを利用するには use
を使ってパスを指定します:
use crate::M1::M2::M3::hoge;
use std::fmt::Result;
use
で指定したパスに as
で別名をつけられます:
use std::io::Result as IoResult;
use
で指定するパスにおいて,あるモジュールから別々のパスを指定する場合,それぞれのパスを use
で指定すると必要な行が増えてしまいます.そこで,パスのリストを記述できます:
use crate::M1::{M2::M3, M4};
また,あるモジュール以下をすべて現在のスコープで利用する場合はグロブ(*
)を指定できます:
use crate::M1::*;
📌 モジュールツリー
クレートそのものがモジュールであり,クレートルートは src/main.rs
ファイルで,パスは crate
でした.Rust のモジュールシステムはクレートルート以下のフォルダとファイルもまたモジュールと見なします.これによって別々のファイルに実装を分けられます.
mod
では {}
で囲む他に,指定した名前と同じファイルを同じフォルダ内から検索して,その中身を挿入できます.例えば, src/hoge.rs
というファイルがあるとします. src/main.rs
から mod hoge;
とすれば src/hoge.rs
の中身を src/main.rs
ファイルに挿入します.ここで src/hoge.rs
の中身が次のようになっているとします.
pub fn hoge() {}
この場合, src/main.rs
からは crate::hoge::hoge()
で呼び出せます.このフォルダとファイルによるモジュールの作り方が2種類あります.
🔹 Rust2015方式
下図のようなフォルダ構成を考えます.このような構成にすると, src/main.rs
から mod module1;
とすることで, src/module1/mod.rs
ファイルが読み込まれます.そのファイルの中身は pub mod foo;
とします.これで,src/main.rs
から src/module1/foo.rs
のモジュールを利用できます.同じように pub mod bar;
を mod.rs
に追加すれば bar.rs
モジュールも利用できるようになります.このようにモジュールの階層を作ってプログラムを構築できます.これを モジュールツリー といいます.
(workspace)
├─ src
│ ├── main.rs
│ └─ module1
│ ├── mod.rs
│ ├── foo.rs
│ └── bar.rs
├── cargo.toml
└── .gitignore
🔹 Rust2018方式
もう1つのモジュールツリーの作り方ですが,下図を見てください.今度は mod.rs
ファイルの代わりに,フォルダと同じファイル module1.rs
が存在しています.このファイルの中身は mod.rs
と同じになります.ファイルの構成が違いますが,モジュールツリーは同じなので,コードに変更はありません.
(workspace)
├─ src
│ ├── main.rs
│ ├── module1.rs
│ └─ module1
│ ├── foo.rs
│ └── bar.rs
├── cargo.toml
└── .gitignore
Rust2015方式ではmod.rs
ファイルが多く作られる問題があります.Rust2018方式ではモジュールのフォルダと同じ名前のファイルを作成することでこの問題を避けることができます.Rust2015方式はとくに非推奨となっているわけではないですし、現時点では好きな方を使えばいいと思います.
📌 モジュールの再公開
pub use
を使うことで,外部モジュールからでも,指定したパスで利用できるようになります.これを再公開といいます.
pub use crate::module1;