コード編成の背後にある概念を理解する

完了

開始する前に、Rust プログラムでのコード編成の背後にある概念について説明することが重要です。

  • パッケージ:
    • 1 つ以上の "クレート" 内に機能が含まれています。
    • これらの "クレート" をビルドする方法に関する情報が含まれています。 情報は Cargo.toml ファイル内にあります。
  • クレート:
    • コンパイル単位です。これは、Rust コンパイラが動作できる最小のコード量です。
    • コンパイルが完了すると、実行可能ファイルまたはライブラリが生成されます。
    • 暗黙的な、名前のないトップレベル "モジュール" が含まれています。
  • モジュール:
    • "クレート" 内の "(入れ子になっている可能性がある)" コード編成の単位です。
    • 追加のモジュールにまたがる再帰的な定義が含まれる場合があります。

パッケージ

コマンド $ cargo new <project-name> を実行するたびに、Cargo によってパッケージが作成されます。

$ cargo new my-project
     Created binary (application) `my-project` package

ここでは、src/main.rs のみが含まれているパッケージを使用しています。つまり、my-project という名前のバイナリ クレートだけが含まれています。

my-project
├── src
│  └── main.rs
└── Cargo.toml

パッケージは、src/bin ディレクトリにファイルを配置することで、複数のバイナリ クレートを持つことができます。 各ファイルが個別のバイナリ クレートになります。

パッケージ内に src/main.rssrc/lib.rs がある場合は、ライブラリとバイナリという 2 つのクレートが含まれています。 これらの両方にパッケージと同じ名前が付けられています。

クレート

Rust のコンパイル モデルは、バイナリまたはライブラリにコンパイルできる、"クレート" と呼ばれる成果物を中心にしています。

cargo new コマンドを使用して作成したすべてのプロジェクトが、クレートそのものです。 プロジェクト内で依存関係として使用できるサードパーティーのすべての Rust コードも、それぞれが 1 つのクレートです。

ライブラリ クレート

バイナリ プログラムを作成する方法については既に説明しましたが、ライブラリの作成も簡単です。 ライブラリを作成するには、--lib コマンドライン パラメーターを cargo new コマンドに渡します。

$ cargo new --lib my-library
     Created library `my-library` package

src/main.rs ファイルの代わりに、=src/lib.rs' ファイルが取得されていることを確認できます。

my-library
├── src
│  └── lib.rs
└── Cargo.toml

このクレートをコンパイルするように Cargo に指示すると、libmy_library.rlib という名前のライブラリ ファイルが作成され、他のプロジェクトにパブリッシュしてリンクすることができます。

モジュール

Rust は、階層的に論理的なユニットに分割し、読みやすく再利用しやすい、強力なモジュール システムを提供します。

モジュールは、以下の項目のコレクションです。

  • 定数
  • 型の別名
  • 関数
  • 構造体
  • 列挙型
  • Traits
  • impl のブロック
  • その他のモジュール

モジュールは、項目の "プライバシー" も制御します。 項目のプライバシーにより、項目が "公開" または "非公開" のいずれかとして識別されます。 公開は、項目が外部コードで使用できることを意味します。 非公開は、項目が内部実装の詳細であり、外部で使用できないことを意味します。

モジュールの例を示します。

mod math {
    type Complex = (f64, f64);
    pub fn sin(f: f64) -> f64 { /* ... */ }
    pub fn cos(f: f64) -> f64 { /* ... */ }
    pub fn tan(f: f64) -> f64 { /* ... */ }
}

println!("{}", math::cos(45.0));

ソース ファイルに mod 宣言が含まれている場合は、これにコンパイラを実行する前に、ソース ファイル内の mod 宣言がある場所にモジュール ファイルの内容が挿入されます。 つまり、モジュールは個別にはコンパイルされず、クレートのみがコンパイルされます。

math モジュールの関数定義の先頭に、pub キーワードがあることにお気づきかもしれません。

Rust コンパイラによって、項目がモジュール間で使用できるかどうかが確認されます。 既定では、Rust 内のすべてのものがプライベートであり、現在のモジュールとその子孫のみがアクセスできます。 これに対して、項目が pub として宣言されている場合は、外部からアクセスできると考えることができます。 次に例を示します。

// Declare a private struct
struct Foo;

// Declare a public struct with a private field
pub struct Bar {
    field: i32,
}

// Declare a public enum with two public variants
pub enum State {
    PubliclyAccessibleVariant,
    PubliclyAccessibleVariant2,
}

Rust のプライバシー規則は、内部実装の詳細を非表示にしながら、パブリック API を公開するモジュール階層を作成する場合に、驚くような力を発揮します。