Chapter 24

モジュール

📌 モジュールを定義

モジュールの定義は 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 のモジュールシステムはクレートルート以下のフォルダとファイルもまたモジュールと見なします.これによって別々のファイルに実装を分けることが出来るわけです.このフォルダとファイルによるモジュールの作り方が2種類あります.先に一般的な方法を説明します.

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() で呼び出すことが出来ます.

次に下図のようなフォルダ構成を考えます.このような構成にすると, 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

rust-moduletree01

もう1つのモジュールツリーの作り方ですが,下図を見てください.今度は mod.rs ファイルの代わりに,フォルダと同じファイル module1.rs が存在しています.このファイルの中身は mod.rs と同じになります.ファイルの構成が違いますが,モジュールツリーは同じなので,コードに変更はありません.

(workspace)
├─ src
│   ├── main.rs
│   ├── module1.rs
│   └─ module1
│       ├── foo.rs
│       └── bar.rs
├── cargo.toml
└── .gitignore
        \end{code}
    \end{minipage}

rust-moduletree02

📌 モジュールの再公開

pub use を使うことで,外部モジュールからでも,指定したパスで利用できるようになります.これを再公開といいます.

pub use crate::module1;