🚀

async/await — Rustの非同期プログラミング

Futureトレイトベース、ランタイム選択が自由な非同期モデル

JavaScriptのasync/awaitと文法は似ているが内部動作が異なる。Rustのasync fnはFutureトレイトを実装する状態マシンにコンパイルされる。ヒープ割り当ても最小化。

async fn fetch_data(url: &str) -> Result<String, Error> {
    let response = reqwest::get(url).await?;
    let body = response.text().await?;
    Ok(body)
}

Rust標準ライブラリには非同期ランタイムが含まれていない。tokio(最も人気)やasync-stdを自分で持ち込む。この設計のおかげで組み込み環境では軽量ランタイムを、サーバーでは高性能ランタイムを選べる。

PinとSelf-Referential Future

asyncブロックが.awaitを越えてローカル変数への参照を保持すると自己参照構造になる。これを安全に扱うためにPinが存在する。ここがRust asyncの最も難しい部分だ。

キーポイント

1

async fnはFutureトレイトを実装する状態マシンにコンパイル

2

.awaitでランタイムに制御を譲渡(yield)— 他タスクが実行

3

tokio::spawnで非同期タスクをスケジューラに登録

4

#[tokio::main]でランタイム初期化+mainをasyncに

メリット

  • ゼロコスト — Futureが状態マシンにコンパイル、ヒープ割り当て最小
  • ランタイム交換可能 — tokio、async-std、smol等

デメリット

  • asyncトレイトが最近まで不安定だった(RPITITで安定化進行中)
  • Pin/Unpinの概念が難しい
  • ライブラリがtokio vs async-stdに分かれるエコシステム分裂

ユースケース

Webサーバー(axum、actix-web)— 少数スレッドで数千同時接続を処理 HTTPクライアント(reqwest)— 同時多重リクエスト