ここはいまだに理解があいまいだから、しっかりやりたい。
## [[パッケージ (Rust)|パッケージ]]と[[クレート]]
- `src/main.rs`が[[パッケージ (Rust)|パッケージ]]と同じ名前の[[バイナリクレート]]の[[クレートルート]]
- `src/lib.rs`が[[パッケージ (Rust)|パッケージ]]と同じ名前の[[ライブラリクレート]]の[[クレートルート]]
- `src/bin`ディレクトリに置くと[[パッケージ (Rust)|パッケージ]]が複数の[[バイナリクレート]]を持つことができる??
## [[モジュール (Rust)|モジュール]]を定義して、スコープとプライバシーを制御する
- [[モジュール (Rust)|モジュール]]はプライバシーを制御できる (public/private)
```rust
mod hoge {
mod huga {
fn hige() {}
}
}
```
## モジュールツリーの要素を示すためのパス
- [[モジュールツリーの絶対パス]]
- [[モジュールツリーの相対パス]]
- 自分の[[モジュール (Rust)|モジュール]]に定義されているモノは`pub`でなくても見える
- ただその子や孫は`pub`がないと見えない
- `super`を使った相対パスだと、[[モジュール (Rust)|モジュール]]が別の場所に移動した時の影響は少なくなる
- [[Enum (Rust)|Enum]]を`pub`で公開すると、すべての[[ヴァリアント (Rust)|ヴァリアント]]は公開される
- [[ヴァリアント (Rust)|ヴァリアント]]に`pub`は不要
- [[構造体 (Rust)|構造体]]は非公開にすると便利なことがあるのでデフォルトpubとはなっていない
## [[useキーワード]]でパスをスコープに持ち込む
`use aaa::bbb::ccc`で`ccc`[[モジュール (Rust)|モジュール]]の関数などを`ccc:hoge(...)`のように呼べる。
- どこまで`use`するか問題
- [[Rustで別モジュールの関数を利用する場合は、関数の親モジュールをuseする]]
- [[Rustで別モジュールの関数以外を利用する場合は、対象の名称をuseする]]
- `use std::io::Result as IoResult`のようにすれば別名も可能
- これも慣例とみなされているらしい
- [[再公開]]を使うことで内部的な構造を隠蔽したまま、一部の要素を外部公開できる
- ただ以下の例では `outer::inner::User`も受け付ける
- これが同一ファイルのテストコードだからかどうかは不明
- `mod outer`ってprivateにはならん?
```rust
mod outer {
pub mod inner {
pub struct User {
pub id: i32,
pub name: String,
}
}
}
pub use outer::inner::User;
#[cfg(test)]
mod tests {
// use super::outer::inner::User より簡潔
use super::User;
#[test]
fn test_hoge() {
let user = User {
id: 1,
name: "てすと".to_string(),
};
assert_eq!(user.id, 1);
}
}
```
- 標準ライブラリでも[[useキーワード]]は使う
- ただし[[prelude]]除く
- 複数の要素を`use`する場合は`use std::{cmp::Ordering, io}`のように表現できる
- `use std::io`と`use std::io::Write`のような場合は`self`を使って表現できる
- `use std::io{self, Write}`
- [[glob]]を使って `use std::collections::*` みたいな表現もできる
- 基本的に使わない方がいい.. どこで何が使われているか分かりにくくなる
- ただ、[[ユニットテスト]]で `use super::*` のように使うと便利
- それ以外だと[[プレリュードパターン]]くらい
## モジュールを複数のファイルに分割する
- `mod hoge;` は[[モジュール (Rust)|モジュール]]をモジュール名と同じ名前のファイルから読み込む命令
- この場合は `hoge.rs`
- ==`mod hoge {}` の定義があるわけではないので注意==
- `mod hoge {}`の使う側は`use hoge`
- `hoge.rs`の使う側は`mod hoge`
- `/app.rs`の`pub mod translation`が、`app/translation.rs`を読み込む理由はしっくりこないなあ...
```rust
// front_of_house.rsを読み込んで...
mod front_of_house;
// front_of_house.rsに定義されたhostingモジュールを使う
pub use crate::front_of_house::hosting;
```
`src/front_of_house.rs`
```rust
pub mod hosting {
pub fn add_to_waitlist() {}
}
```
上記とは同じ意味合いで以下の構成にすることもできる。
`src/front_of_house.rs`
```rust
pub mod hosting;
```
`src/front_of_house/hosting.rs`
```rust
pub fn add_to_waitlist() {}
```
[[モジュールツリー]]が大きくなってくると可読性が相対的に上がるので便利。
```console
src
lib.rs
front_of_house.rs
front_of_house
hosting.rs
```