はじめに
Cargo、cargo build と cargo run しか使ってない人いませんか?
もったいない!!
Cargoには便利な機能がたくさんあります。今回は「これ知ってたら開発が捗る」機能を10個紹介します。
目次
- cargo watch
- cargo clippy
- cargo fmt
- cargo expand
- cargo tree
- cargo doc
- cargo bench
- cargo fix
- cargo audit
- cargo-edit
1. cargo watch
ファイル変更を監視して自動でコマンド実行
# インストール
cargo install cargo-watch
# 使い方
cargo watch -x run # 変更があったらcargo run
cargo watch -x test # 変更があったらcargo test
cargo watch -x check # 変更があったらcargo check(高速)
便利なオプション
# クリアして実行
cargo watch -c -x run
# 複数コマンド
cargo watch -x check -x test -x run
# 特定ファイルを無視
cargo watch -i "*.txt" -x run
# 遅延実行(デバウンス)
cargo watch -d 2 -x run # 2秒待ってから実行
これがないと開発できない体になりました。
2. cargo clippy
Rustの静的解析ツール(リンター)
# 標準で入っている
cargo clippy
出力例
warning: redundant clone
--> src/main.rs:10:22
|
10 | let s2 = s1.clone();
| ^^^^^^^ help: remove this
|
= note: `#[warn(clippy::redundant_clone)]` on by default
「そのclone要らないよ」とか「もっと良い書き方あるよ」って教えてくれる。
便利なオプション
# 警告をエラーとして扱う
cargo clippy -- -D warnings
# 特定のlintを有効化
cargo clippy -- -W clippy::pedantic
# 自動修正
cargo clippy --fix
Clippy の厳しさレベル
// Cargo.toml
[lints.clippy]
pedantic = "warn" # より厳しいチェック
nursery = "warn" # 実験的なチェック
3. cargo fmt
コードフォーマッター
# 標準で入っている
cargo fmt # フォーマット実行
cargo fmt --check # チェックのみ(CI用)
設定ファイル
rustfmt.toml をプロジェクトルートに置く:
# rustfmt.toml
max_width = 100
tab_spaces = 4
use_small_heuristics = "Max"
imports_granularity = "Crate"
group_imports = "StdExternalCrate"
CI での使い方
# GitHub Actions
- name: Check formatting
run: cargo fmt --all --check
4. cargo expand
マクロの展開結果を表示
# インストール
cargo install cargo-expand
# 使い方
cargo expand # 全体
cargo expand main # 特定の関数
cargo expand --lib # libのみ
例
// 展開前
fn main() {
println!("Hello, {}!", "world");
}
// cargo expand の出力
fn main() {
{
::std::io::_print(
format_args!("Hello, {0}!\n", "world")
);
};
}
マクロのデバッグに必須。
5. cargo tree
依存関係のツリー表示
# 標準で入っている
cargo tree
出力例
my-project v0.1.0
├── serde v1.0.193
│ └── serde_derive v1.0.193
│ ├── proc-macro2 v1.0.70
│ ├── quote v1.0.33
│ └── syn v2.0.41
└── tokio v1.35.0
├── bytes v1.5.0
├── mio v0.8.10
└── ...
便利なオプション
# 重複パッケージを表示
cargo tree -d
# 特定パッケージがなぜ依存されているか
cargo tree -i serde
# フィーチャーを表示
cargo tree -f "{p} {f}"
# 深さを制限
cargo tree --depth 2
「なんでこのクレートが入ってるの?」を調べるときに便利。
6. cargo doc
ドキュメント生成
# 標準で入っている
cargo doc --open # ドキュメント生成してブラウザで開く
cargo doc --no-deps # 依存クレートは除外
cargo doc --document-private-items # privateも含む
ドキュメントコメント
/// ユーザーを表す構造体
///
/// # Examples
///
/// ```
/// let user = User::new("Alice", 20);
/// assert_eq!(user.name(), "Alice");
/// ```
pub struct User {
name: String,
age: u32,
}
/// で書いたコメントがドキュメントになる。
doctestとして実行
cargo test --doc
ドキュメント内のコード例がテストとして実行される。
7. cargo bench
ベンチマーク
# Nightly必須(標準のベンチマーク)
cargo +nightly bench
criterion を使う(Stable で可能)
# Cargo.toml
[dev-dependencies]
criterion = "0.5"
[[bench]]
name = "my_benchmark"
harness = false
// benches/my_benchmark.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion};
fn fibonacci(n: u64) -> u64 {
match n {
0 => 0,
1 => 1,
n => fibonacci(n - 1) + fibonacci(n - 2),
}
}
fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("fib 20", |b| {
b.iter(|| fibonacci(black_box(20)))
});
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
cargo bench
8. cargo fix
自動修正
# 標準で入っている
cargo fix # 警告を自動修正
cargo fix --edition # エディション移行
cargo fix --allow-dirty # コミットしてなくても実行
エディション移行
# Rust 2018 → 2021
cargo fix --edition
Cargoが古い書き方を新しい書き方に自動変換してくれる。
9. cargo audit
脆弱性チェック
# インストール
cargo install cargo-audit
# 使い方
cargo audit
出力例
Crate: regex
Version: 1.5.4
Title: Denial of service in regex
Date: 2022-01-01
ID: RUSTSEC-2022-0001
URL: https://rustsec.org/advisories/RUSTSEC-2022-0001
Severity: medium
Dependency tree:
regex 1.5.4
└── my-project 0.1.0
依存クレートの脆弱性をチェックしてくれる。CIに組み込むと安心。
CI での使い方
# GitHub Actions
- name: Security audit
run: |
cargo install cargo-audit
cargo audit
10. cargo-edit
依存関係の追加・削除をCLIで
# インストール
cargo install cargo-edit
# 使い方
cargo add serde # 依存追加
cargo add serde --features derive # フィーチャー付き
cargo add tokio@1.0 # バージョン指定
cargo rm serde # 依存削除
cargo upgrade # 依存を最新に
Before
# Cargo.toml を手動で編集...
After
cargo add serde --features derive
cargo add tokio --features full
これだけで Cargo.toml が更新される。
おまけ:知っておくと便利なコマンド
cargo check
cargo check # コンパイルチェックのみ(バイナリ生成なし)
cargo build より圧倒的に速い。
cargo clean
cargo clean # target/ を削除
ディスク容量が足りなくなったらこれ。
cargo update
cargo update # Cargo.lock を更新
cargo update -p serde # 特定クレートのみ
環境変数
CARGO_INCREMENTAL=0 cargo build # インクリメンタルビルド無効
RUST_BACKTRACE=1 cargo run # バックトレース表示
RUSTFLAGS="-C target-cpu=native" cargo build --release # 最適化
まとめ
必須ツール
| ツール | 用途 |
|---|---|
| cargo watch | 自動ビルド |
| cargo clippy | リンター |
| cargo fmt | フォーマッター |
| cargo-edit | 依存管理 |
CIに入れたいツール
| ツール | 用途 |
|---|---|
| cargo clippy | コード品質 |
| cargo fmt --check | フォーマット |
| cargo audit | 脆弱性 |
デバッグに便利
| ツール | 用途 |
|---|---|
| cargo expand | マクロ展開 |
| cargo tree | 依存関係 |
チェックリスト
-
cargo watchをインストールして開発効率UP -
cargo clippyを習慣的に実行 -
cargo fmtでフォーマットを統一 -
CIに
auditとclippyを組み込む
今すぐできるアクション
# 全部インストール
cargo install cargo-watch cargo-expand cargo-audit cargo-edit
Cargo、めちゃくちゃ便利です。使いこなすと開発体験が全然違う。
この記事が役に立ったら、いいね・ストックしてもらえると嬉しいです!