핵심 요약
Rust 1.85의 async closures 정식. async Fn/FnMut/FnOnce traits로 클로저가 async future 반환. Tokio·tower middleware 4개월 적용, boilerplate -38%, 가독성 향상.
1. 1.85 이전 vs 이후
// 이전 — Box pin 강제
fn run(f: F) where F: Fn() -> Pin>> {
futures::executor::block_on(f())
}
// 1.85 — async closure 표준
fn run i32>(f: F) {
futures::executor::block_on(f())
}
run(async || compute().await)
2. tower middleware 패턴
use tower::Service;
let svc = service_fn(async |req: Request| {
let user = auth(&req).await?;
let res = handler(req).await?;
log_metrics(&user, &res).await;
Ok(res)
});
middleware composition이 한 함수로 표현. 기존 manual Service impl 100줄 → async fn 10줄.
3. 실측 — 코드 변화
| 파일 | Before | After |
|---|---|---|
| auth middleware | 82 lines | 28 lines |
| db transaction wrapper | 120 lines | 42 lines |
| event handler | 180 lines | 94 lines |
4. Send/Sync bound 변경
async closures는 capture 변수의 Send 여부에 따라 자동 추론. 명시 bound 거의 불필요. 단 thread-spawned tokio task 필요 시 explicit Send 마커.
5. 함정
- lifetime — closure capture borrow 자동 추론하지만 명시 'a 필요한 경우 일부
- move keyword — captured 변수 ownership 명시 안 하면 borrow checker fail
- trait bound — AsyncFn vs Fn 구분, Fn은 sync, AsyncFn은 async future 반환
- 3rd-party crate 호환 — tower 0.6+, axum 0.8+ 필수, 옛 버전 호환 부분

댓글 0