Rust独学メモ2
モジュール
Rustにおけるモジュールは、C++における名前空間のようなもの。アクセス指定子を付けることによって公開・非公開をコントロールできる。
Start from the crate root: When compiling a crate, the compiler first looks in the crate root file (usually src/lib.rs for a library crate or src/main.rs for a binary crate) for code to compile.
コンパイルはクレート・ルートから始まり、クレート内の階層化されたモジュールの宣言はこのファイルに書く。
Declaring modules: In the crate root file, you can declare new modules; say, you declare a “garden” module with mod garden;. The compiler will look for the module’s code in these places:
- Inline, within curly brackets that replace the semicolon following mod garden
- In the file src/garden.rs
- In the file src/garden/mod.rs
モジュールの定義の仕方は1+2=3通りから選べる
- mod garden { ... } のようにモジュール宣言の直後に括弧でスコープ作って、インラインで定義する方法
- あるいは、mod garden; のように、forward declaration した場合、コンパイラは
- モジュールと同名の .rs ファイル(src/garden.rs )か、
- モジュールと同名のフォルダ内の mod.rs ファイル(src/garden/mod.rs)に、定義を探しに行く
⇒ Rust のソースファイルは1つのモジュールに対応している(大胆!)
⇒ モジュールとして提供する機能が複数ファイルに及ぶような場合はサブモジュールを作って、use キーワードでインポートする運用(つらい)
クレート・ルート以外のモジュール内でも同様にサブモジュールを定義出来て、
- mod vegetables { ... } のように、モジュール内にインラインで書くか
- サブモジュールと同名の .rs ファイルをサブフォルダに置く(src/garden/vegetables.rs)か、
- サブモジュールと同名のサブフォルダのサブフォルダに mod.rs を置く(src/garden/vegetables/mod.rs)とのこと
⇒ ファイル・ディレクトリの構造以上にモジュールの構造が散らからない。クレート全体がコンパイル単位なので、クレート内では自由に相互依存ができる。スコープ演算子によるモジュールパスの解決、pub、use は、特筆することはなさそう
まとめ
- Rust のモジュール階層は、クレート・ルートから芋づる式に定義される
- ファイル、あるいはフォルダ + mod.rs を見たら、それがモジュールの定義
- use を使って適度にモジュールを統合しないと :: だらけの悲惨なコードになりそう。どれくらい :: を使うか、どのように使わせるかという塩加減は、おそらく長期的には重要なスキルになると思う
感想
1ファイルをモジュールに対応させたり、root のモジュールを crate と呼んだり、言語の内部実装に利用者が付き合わされて(振り回されて)いる感じがするものの、インクルードパスとか気にしなくても良いし、実用には耐えそう。