🚀
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
キーポイント
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)— 同時多重リクエスト