本文へスキップ
BecomeCoder

Rustコース · 第12章 プロジェクトとツール · レッスン46

Cargo とモジュールシステム ― mod・use・crate

ローカル実施

導入

ここまでのレッスンは、実行ウィジェットの中で完結する短いコードでした。しかし実際のRust開発では、ファイルを分割し、外部のライブラリ(crate)を取り込みながらプロジェクトを組み立てます。それを支えるのが公式のビルドツール Cargo と、コードを整理するモジュールシステムです。

説明

Cargo は Rust のビルド・パッケージ管理ツールです。rustc を直接呼ぶことはほとんどなく、実務ではまず Cargo を使います。

cargo new my_app       # 新しいプロジェクトを作る(Cargo.toml と src/main.rs が生成される)
cargo build             # コンパイルする(成果物は target/ 以下)
cargo run                # ビルドしてすぐ実行する
cargo test                # テストを実行する(レッスン47で扱います)
cargo add serde          # crates.io から依存を追加する

プロジェクトの中心には Cargo.toml という設定ファイルがあります。

[package]
name = "my_app"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = "1.0"
rand = "0.8"
  • [package] … プロジェクト名やバージョンなどのメタ情報。
  • [dependencies] … 使う外部クレート(ライブラリ)とバージョン。cargo add で書き足すこともできますし、手で編集しても構いません。cargo build を実行すると、ここに書かれた依存を crates.io(Rustの公式パッケージレジストリ)から取得してビルドします。

コードが大きくなると、1つのファイルに全部書くのは辛くなります。Rust では mod でモジュール(コードのまとまり)を作り、use で他のモジュールの名前を持ち込み、pub で外から見える範囲を制御します。

// src/main.rs
mod greetings {
    pub fn hello(name: &str) -> String {
        format!("Hello, {name}!")
    }

    pub mod formal {
        pub fn greet(name: &str) -> String {
            format!("Good day, {name}.")
        }
    }
}

use greetings::formal::greet;

fn main() {
    println!("{}", greetings::hello("Rust"));
    println!("{}", greet("Rustacean"));
}
  • mod greetings { ... }greetings という名前のモジュールを作ります。中の fn hellopub を付けないと、モジュールの外から呼べません。
  • mod formal はさらにその中の入れ子のモジュールです。深いモジュールへは greetings::formal::greet のように :: でたどります。
  • use greetings::formal::greet; … 長いパスを毎回書かなくて済むよう、名前を持ち込みます(他言語の import に近い感覚です)。

実際のプロジェクトでは、mod greetings { ... } とインラインで書く代わりに、mod greetings; とだけ書いて src/greetings.rs(または src/greetings/mod.rs)という別ファイルにモジュールの中身を分割するのが一般的です。ファイルが1つのモジュールに対応する、という構造です。

graph TD
    crate["クレートルート(src/main.rs か src/lib.rs)"]
    crate --> greetings["mod greetings(src/greetings.rs)"]
    greetings --> hello["pub fn hello"]
    greetings --> formal["pub mod formal(src/greetings/formal.rs)"]
    formal --> greet["pub fn greet"]

クレートルートは、実行可能プログラムなら src/main.rs、ライブラリなら src/lib.rs です。ここがモジュール木の根っこになり、mod 宣言がすべてここから枝分かれしていきます。1つのプロジェクト(パッケージ)は、実行可能な crate とライブラリの crate の両方を持てます。

まとめ

  • cargo new/build/run/test/add が開発の基本サイクル。Cargo.toml が依存とメタ情報を持つ。
  • mod でモジュールを作り、pub で公開範囲を制御し、use で名前を持ち込む。
  • クレートルートは main.rs(実行可能)か lib.rs(ライブラリ)で、そこからモジュール木が伸びていく。
  • 大きくなったら mod greetings; +別ファイルに分割するのが定番。