到達点は、公開するAPIと内部実装を分けることです。前提は第09回です。
ファイルと名前空間を対応させる
クレートはコンパイルの単位で、ライブラリにも実行プログラムにもなります。パッケージはCargo.tomlで管理され、複数のクレートを含む場合があります。モジュールはクレート内の名前空間と公開範囲を整理します。
cargo new module-practice --edition 2024 で作ったフォルダへ移動し、src/lib.rsを追加します。
pub mod fees {
pub fn shipping(amount: u32) -> u32 {
if amount >= 5000 { 0 } else { 500 }
}
}
src/main.rsを次に変えます。パッケージ名のハイフンは、コードで使うクレート名ではアンダースコアになります。
use module_practice::fees::shipping;
fn main() {
println!("{}", shipping(4999));
println!("{}", shipping(5000));
}
cargo runで500と0を確認します。さらに分けたければsrc/lib.rsを pub mod fees; とし、関数をsrc/fees.rsへ移します。modはモジュールを定義・宣言し、useは名前を現在のスコープへ取り込むもので、役割が違います。
公開範囲は小さく始める
pubは外部へ公開し、pub(crate)はクレート内へ公開します。内部のデータ表現をすべて公開すると、後で変更しにくくなります。利用者に約束する操作だけを公開し、内部の補助関数は隠します。
依存はCargo.tomlへ書き、解決された版はCargo.lockへ記録します。featureは依存の任意機能を選ぶ仕組みで、すべてを有効にする前に必要なものを考えます。workspaceは関連する複数パッケージをまとめる方法です。最初から分割しすぎず、独立した変更や再利用の理由が出たら検討します。
練習と解答
練習:shippingのpubを外すと、mainから使えるでしょうか。
解答:この構成のmainとlibは別クレートなので、その関数を公開しなければ呼べません。単に同じフォルダのプロジェクトにあることと、Rustの公開境界は同じではありません。コンパイラが示すprivateの場所を確認します。
公式資料
モジュールと公開範囲とCargo Bookが参照先です。
Rust全20回の目次 | 前の回 | 次の回