[Rustのはじめ方] Part21: 外部クレートの利用(Cargo.toml)

外部クレートとは? なぜ使うの?

Rustの開発では、標準ライブラリ(std)だけではカバーしきれない機能が必要になることがよくあります。例えば、乱数生成、HTTPリクエストの送信、JSONデータの解析などです。

このような場合に役立つのが外部クレート(External Crates)です。外部クレートは、Rustコミュニティによって開発され、crates.ioという公式のパッケージレジストリで公開されているライブラリのことです。

外部クレートを利用することで、車輪の再発明を避け、効率的に開発を進めることができます。Rustのエコシステムは非常に活発で、多種多様なクレートが存在します 🚀。

Cargo.toml と [dependencies] セクション

プロジェクトがどの外部クレートに依存しているかを管理するのが、プロジェクトルートにある Cargo.toml ファイルです。このファイルの中の [dependencies] セクションに、利用したいクレートとそのバージョンを指定します。

cargo new でプロジェクトを作成した直後の Cargo.toml は以下のようになっています。

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

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
# ここに依存クレートを追記していく

[dependencies] セクションにクレートを追加することで、Cargoが自動的にそのクレートをダウンロードし、ビルド時にリンクしてくれます。

外部クレートを追加する方法

外部クレートを追加するには、主に2つの方法があります。

1. `Cargo.toml` を手動で編集する

crates.io で利用したいクレートを検索し、そのクレートのページに記載されている情報を Cargo.toml[dependencies] セクションに追記します。

例えば、乱数を生成するための人気クレート rand を追加したい場合、以下のように記述します(バージョンは執筆時点のものを例としています)。

[dependencies]
rand = "0.8" # rand クレートのバージョン 0.8 系を追加

バージョン番号は、利用したいクレートの crates.io のページで確認できます。

2. `cargo add` コマンドを使う (推奨 ✨)

より簡単な方法として、cargo add コマンドがあります。このコマンドを使うと、自動的に Cargo.toml に適切な行が追加されます。

例えば、rand クレートを追加するには、ターミナルでプロジェクトのルートディレクトリに移動し、以下のコマンドを実行します。

cargo add rand

これにより、Cargo.toml に最新の互換性のあるバージョンが自動的に追記されます。特定のバージョンを指定したい場合は、@ の後にバージョン番号を付けます。

cargo add rand@0.8.5

cargo add コマンドは Rust 1.62.0 以降で標準機能として利用可能です。

バージョン指定の仕方 ⚙️

Cargo.toml でクレートのバージョンを指定する方法はいくつかあります。Cargoはセマンティックバージョニング (SemVer) に従っています。

一般的な指定方法をいくつか紹介します。

記法例 意味 説明
"0.8.5" ^0.8.5 と同じ デフォルトの記法(キャレット要件)。0.8.5 以上 0.9.0 未満の最新バージョンを許可します。最も一般的に使われます。
"^0.8.5" >=0.8.5, <0.9.0 キャレット要件。上記と同じ意味です。互換性のあるマイナーバージョン、パッチバージョンの更新を許可します。
"1.2" ^1.2 と同じ (>=1.2.0, <2.0.0) 1.2.0 以上 2.0.0 未満の最新バージョンを許可します。
"1" ^1 と同じ (>=1.0.0, <2.0.0) 1.0.0 以上 2.0.0 未満の最新バージョンを許可します。
"=1.2.3" =1.2.3 バージョン 1.2.3 に完全に固定します。通常は推奨されません。更新が適用されなくなります。
"~1.2.3" >=1.2.3, <1.3.0 チルダ要件。パッチバージョンの更新のみを許可します。
"*" * 任意のバージョンを許可します。互換性のない変更が含まれる可能性があり、危険なため非推奨です。
">=1.0, <2.0" >=1.0, <2.0 比較要件。より複雑なバージョン範囲を指定できます。

📝 補足: 通常は、"0.8.5""1.2" のようなデフォルトのキャレット要件を使うのがベストプラクティスです。これにより、互換性を保ちつつ、バグ修正や機能追加の恩恵を受けやすくなります。バージョンを厳密に固定したい場合は Cargo.lock ファイルがその役割を果たします(これはCargoが自動生成・管理します)。

ビルドとクレートの利用

Cargo.toml に依存クレートを追加した後、cargo buildcargo run を実行すると、Cargoは自動的に以下の処理を行います。

  1. crates.io から指定されたクレート(とそのクレートが依存する他のクレート)をダウンロードします。
  2. ダウンロードしたクレートをコンパイルします。
  3. 自分のプロジェクトをコンパイルし、依存クレートとリンクします。

初回ビルド時はクレートのダウンロードとコンパイルに時間がかかることがありますが、2回目以降はキャッシュが利用されるため高速になります。

コードでの利用方法

クレートをコード内で利用するには、use キーワードを使います。例えば、rand クレートを使って0から9までのランダムな数値を生成するコードは以下のようになります。

// src/main.rs
use rand::Rng; // rand クレートの Rng トレイトをインポート

fn main() {
    let mut rng = rand::thread_rng(); // スレッドローカルな乱数生成器を取得
    let n: u32 = rng.gen_range(0..10); // 0以上10未満の範囲で乱数を生成
    println!("Random number: {}", n);
}

まず Cargo.tomlrand を追加します。

[dependencies]
rand = "0.8"

次に、上記のRustコードを src/main.rs に記述し、cargo run を実行すると、ランダムな数値が出力されます。

$ cargo run
   Compiling autocfg v1.1.0
   Compiling libc v0.2.139
   Compiling cfg-if v1.0.0
   Compiling ppv-lite86 v0.2.17
   Compiling getrandom v0.2.8
   Compiling rand_core v0.6.4
   Compiling rand_chacha v0.3.1
   Compiling rand v0.8.5
   Compiling my_project v0.1.0 (/path/to/my_project)
    Finished dev [unoptimized + debuginfo] target(s) in 2.85s
     Running `target/debug/my_project`
Random number: 7 # (実行ごとに異なる数値が表示されます)

まとめ

今回は、外部クレートをプロジェクトに追加し、利用する方法について学びました。

  • 外部クレートは crates.io で公開されているライブラリです。
  • Cargo.toml[dependencies] セクションで依存関係を管理します。
  • cargo add コマンドを使うと簡単にクレートを追加できます。
  • バージョン指定にはセマンティックバージョニングが使われ、通常はキャレット要件 ("0.8""1.2.3") を使います。
  • cargo buildcargo run で、Cargoが自動的にクレートをダウンロード・コンパイルします。
  • コード内では use キーワードでクレートの機能を利用します。

外部クレートを活用することで、Rustでの開発がより強力で効率的になります。様々なクレートを探して、自分のプロジェクトに役立ててみましょう!💪