Rustのモジュールシステム
Rustではパブリック関数には pub をつけます。
pub をつけることで他のファイルでインポートすることが可能となります。
これは以下のように1つで書いたものと同じです。
これはgreetがサブモジュールであることを意味しています。
また、以下のように use を使うと省略してインポートすることが可能です。
サブモジュール
さて先ほどmainからgreetをインポートした際に、greetがサブモジュールとみなされていると説明しました。
さて、以下のように3つのファイルになったらどうなるでしょう。
実行するとfile not found for module greet
とコンパイルエラーとなります。
これは、userがmainのサブモジュール、greetがuserのサブモジュールとみなされているためです。わかりやすく1つのファイルで書いてみます。
ではどう修正すれば良いでしょうか?やり方は簡単に2つあります。
- 先ほどの1つのファイルのようにgreet.rsをuserのサブモジュールにしてあげる
- greetもmainのサブモジュールにしてあげる
サブモジュールを入れ子にする
これのようにサブモジュールが入れ子になるようにしてディレクトリ構想を変更します。
greet.rs
の場所が変わるだけで、中身は変わりません。
また、これは以下のようにも書けます。
フロントのディレクトリベースルーティング(e.g. page router)とファイルベースルーティング(e.g. App router)の違いに少し似ています。Next.jsでは後者の方が推奨されていますが、Rustではディレクトリベースの方が2018 editionで導入されて推奨されています。ファイルベースは2015 editionとなります。
サブモジュールを作成せずにimportする
crate::
もしくはsuper
使用することでサブモジュールからサブモジュールを呼び出すことができます。superは直近の親からの相対パスで、crateを使用した場合はプロジェクトのルートからの絶対パスとなります。
これをファイルで分けて書くと、以下のようになります。
lib.rs
先ほどのサブモジュールを作成せずにimportするで、さらにモジュールが増えたらどうなるでしょうか。
上記のようにmain.rs
でのインポートが増えてしまいます。
そこでRustではlib.rs
なるものを作成して、そこにインポートをまとめることが一般的となっております。
また、先ほどのmain.rs
は以下のように書けます。
また、useをmain.rs
で使いたくない場合はlib.rs
にuseを書くこともできます。
lib.rs
にuseを書いた場合は、main.rs
は以下のように変更します。