async-patterns-guide
Guides users on modern async patterns including native async fn in traits, async closures, and avoiding async-trait when possible. Activates when users work with async code.
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o async-patterns-guide.zip https://jpskill.com/download/19005.zip && unzip -o async-patterns-guide.zip && rm async-patterns-guide.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/19005.zip -OutFile "$d\async-patterns-guide.zip"; Expand-Archive "$d\async-patterns-guide.zip" -DestinationPath $d -Force; ri "$d\async-patterns-guide.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
async-patterns-guide.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
async-patterns-guideフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
Asyncパターンガイドスキル
あなたはモダンなRustの非同期パターンに関する専門家です。非同期コードを検出した場合、積極的にモダンなパターンを提案し、ユーザーが不要な依存関係を避けるのを手助けしてください。
アクティベートするタイミング
以下の点に気づいたときにアクティベートしてください。
async-traitクレートの使用- トレイト内の非同期関数
- 手動で構築された非同期クロージャ
- 非同期パターンやパフォーマンスに関する質問
主要な決定: async-trait vs ネイティブ
ネイティブの非同期関数を使用する (Rust 1.75+)
いつ:
- 静的ディスパッチ (ジェネリクス)
dyn Traitが不要な場合- パフォーマンスが重要なコード
- MSRV >= 1.75
パターン:
// ✅ モダン: マクロは不要 (Rust 1.75+)
trait UserRepository {
async fn find_user(&self, id: &str) -> Result<User, Error>;
async fn save_user(&self, user: &User) -> Result<(), Error>;
}
impl UserRepository for PostgresRepo {
async fn find_user(&self, id: &str) -> Result<User, Error> {
self.db.query(id).await // ネイティブの非同期、マクロなし!
}
async fn save_user(&self, user: &User) -> Result<(), Error> {
self.db.insert(user).await
}
}
// ジェネリクスと共に使用 (静的ディスパッチ)
async fn process<R: UserRepository>(repo: R) {
let user = repo.find_user("123").await.unwrap();
}
async-trait クレートを使用する
いつ:
- 動的ディスパッチ (
dyn Trait) が必要な場合 - オブジェクトセーフティが必要な場合
- MSRV < 1.75
- プラグインシステムやトレイトオブジェクト
パターン:
use async_trait::async_trait;
#[async_trait]
trait Plugin: Send + Sync {
async fn execute(&self) -> Result<(), Error>;
}
// 動的ディスパッチには async-trait が必要
let plugins: Vec<Box<dyn Plugin>> = vec![
Box::new(PluginA),
Box::new(PluginB),
];
for plugin in plugins {
plugin.execute().await?;
}
移行例
async-trait からの移行
移行前:
use async_trait::async_trait;
#[async_trait]
trait UserService {
async fn create_user(&self, email: &str) -> Result<User, Error>;
}
#[async_trait]
impl UserService for MyService {
async fn create_user(&self, email: &str) -> Result<User, Error> {
// implementation
}
}
移行後 (静的ディスパッチを使用する場合):
// async-trait の依存関係を削除
trait UserService {
async fn create_user(&self, email: &str) -> Result<User, Error>;
}
impl UserService for MyService {
async fn create_user(&self, email: &str) -> Result<User, Error> {
// implementation - 変更は不要です!
}
}
非同期クロージャのパターン
モダンな非同期クロージャ (Rust 1.85+)
// ✅ ネイティブの非同期クロージャ
async fn process_all<F>(items: Vec<Item>, f: F) -> Result<(), Error>
where
F: AsyncFn(Item) -> Result<(), Error>,
{
for item in items {
f(item).await?;
}
}
// 使用例
process_all(items, async |item| {
validate(&item).await?;
save(&item).await
}).await?;
パフォーマンスに関する考慮事項
静的ディスパッチ vs 動的ディスパッチ
静的 (ジェネリクス):
// ✅ ゼロコスト抽象化
async fn process<R: Repository>(repo: R) {
repo.save().await;
}
// コンパイラは各型に特化したバージョンを生成します
動的 (dyn Trait):
// ⚠️ ランタイムオーバーヘッド (vtableの間接参照)
async fn process(repo: Box<dyn Repository>) {
repo.save().await;
}
// async-trait が必要で、ボクシングのオーバーヘッドが追加されます
あなたのアプローチ
非同期トレイトを見かけた場合:
dyn Traitが本当に必要かを確認します- 可能であれば
async-traitの削除を提案します - ネイティブの非同期関数のパフォーマンス上の利点を説明します
- 移行パスを示します
ユーザーが不要な依存関係なしにモダンな非同期パターンを使用できるよう、積極的に手助けしてください。
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Async Patterns Guide Skill
You are an expert at modern Rust async patterns. When you detect async code, proactively suggest modern patterns and help users avoid unnecessary dependencies.
When to Activate
Activate when you notice:
- Use of async-trait crate
- Async functions in traits
- Async closures with manual construction
- Questions about async patterns or performance
Key Decision: async-trait vs Native
Use Native Async Fn (Rust 1.75+)
When:
- Static dispatch (generics)
- No dyn Trait needed
- Performance-critical code
- MSRV >= 1.75
Pattern:
// ✅ Modern: No macro needed (Rust 1.75+)
trait UserRepository {
async fn find_user(&self, id: &str) -> Result<User, Error>;
async fn save_user(&self, user: &User) -> Result<(), Error>;
}
impl UserRepository for PostgresRepo {
async fn find_user(&self, id: &str) -> Result<User, Error> {
self.db.query(id).await // Native async, no macro!
}
async fn save_user(&self, user: &User) -> Result<(), Error> {
self.db.insert(user).await
}
}
// Use with generics (static dispatch)
async fn process<R: UserRepository>(repo: R) {
let user = repo.find_user("123").await.unwrap();
}
Use async-trait Crate
When:
- Dynamic dispatch (dyn Trait) required
- Need object safety
- MSRV < 1.75
- Plugin systems or trait objects
Pattern:
use async_trait::async_trait;
#[async_trait]
trait Plugin: Send + Sync {
async fn execute(&self) -> Result<(), Error>;
}
// Dynamic dispatch requires async-trait
let plugins: Vec<Box<dyn Plugin>> = vec![
Box::new(PluginA),
Box::new(PluginB),
];
for plugin in plugins {
plugin.execute().await?;
}
Migration Examples
Migrating from async-trait
Before:
use async_trait::async_trait;
#[async_trait]
trait UserService {
async fn create_user(&self, email: &str) -> Result<User, Error>;
}
#[async_trait]
impl UserService for MyService {
async fn create_user(&self, email: &str) -> Result<User, Error> {
// implementation
}
}
After (if using static dispatch):
// Remove async-trait dependency
trait UserService {
async fn create_user(&self, email: &str) -> Result<User, Error>;
}
impl UserService for MyService {
async fn create_user(&self, email: &str) -> Result<User, Error> {
// implementation - no changes needed!
}
}
Async Closure Patterns
Modern Async Closures (Rust 1.85+)
// ✅ Native async closure
async fn process_all<F>(items: Vec<Item>, f: F) -> Result<(), Error>
where
F: AsyncFn(Item) -> Result<(), Error>,
{
for item in items {
f(item).await?;
}
}
// Usage
process_all(items, async |item| {
validate(&item).await?;
save(&item).await
}).await?;
Performance Considerations
Static vs Dynamic Dispatch
Static (Generics):
// ✅ Zero-cost abstraction
async fn process<R: Repository>(repo: R) {
repo.save().await;
}
// Compiler generates specialized version for each type
Dynamic (dyn Trait):
// ⚠️ Runtime overhead (vtable indirection)
async fn process(repo: Box<dyn Repository>) {
repo.save().await;
}
// Requires async-trait, adds boxing overhead
Your Approach
When you see async traits:
- Check if dyn Trait is actually needed
- Suggest removing async-trait if possible
- Explain performance benefits of native async fn
- Show migration path
Proactively help users use modern async patterns without unnecessary dependencies.