swift-concurrency-pro

swift-concurrency-pro

熱門

審查 Swift 程式碼的並行正確性、現代 API 使用方式,以及常見的 async/await 陷阱。適用於閱讀、撰寫或審查 Swift 並行程式碼時。

492星標
19分支
更新於 2026/5/17
SKILL.md
readonlyread-only
name
swift-concurrency-pro
description

審查 Swift 程式碼的並行正確性、現代 API 使用方式,以及常見的 async/await 陷阱。適用於閱讀、撰寫或審查 Swift 並行程式碼時。

審查 Swift 並行程式碼的正確性、現代 API 使用方式,以及是否符合專案慣例。僅回報真正的問題——不要吹毛求疵或憑空捏造問題。

審查流程:

  1. 使用 references/hotspots.md 掃描已知危險模式,優先檢查哪些項目。
  2. 使用 references/new-features.md 檢查最新的 Swift 6.2 並行行為。
  3. 使用 references/actors.md 驗證 actor 的使用是否正確,包括可重入性與隔離正確性。
  4. 使用 references/structured.md 確保在適當情況下優先使用結構化並行而非非結構化。
  5. 使用 references/unstructured.md 檢查非結構化任務的使用是否正確。
  6. 使用 references/cancellation.md 驗證取消處理是否正確。
  7. 使用 references/async-streams.md 驗證非同步串流與 continuation 的使用。
  8. 使用 references/bridging.md 檢查同步與非同步世界之間的橋接程式碼。
  9. 使用 references/interop.md 審查任何舊版並行遷移。
  10. 使用 references/bug-patterns.md 交叉比對常見的失敗模式。
  11. 如果專案有 strict-concurrency 錯誤,使用 references/diagnostics.md 將診斷對應到修復方式。
  12. 如果審查測試,使用 references/testing.md 檢查非同步測試模式。

如果進行部分審查,只載入相關的參考檔案。

核心指示

  • 目標為 Swift 6.2 或更新版本,並啟用 strict concurrency 檢查。
  • 如果程式碼跨越多個 target 或 package,請先比較它們的並行建置設定,再假設行為應一致。
  • 優先使用結構化並行(task groups)而非非結構化(Task {})。
  • 新程式碼優先使用 Swift 並行而非 Grand Central Dispatch。GCD 在底層程式碼、框架互通或效能關鍵的同步工作中仍可接受,此時佇列與鎖是正確的工具——不要將這些標記為錯誤。
  • 如果 API 同時提供 async/await 與基於閉包的變體,一律優先使用 async/await
  • 未經詢問,不要引入第三方並行框架。
  • 不要建議使用 @unchecked Sendable 來修復編譯器錯誤。它只會壓制診斷,而不會修復底層的競爭問題。應優先使用 actor、值類型或 sending 參數。唯一合法的用途是對於內部有鎖定且可證明執行緒安全的類型。

輸出格式

按檔案組織發現的問題。對於每個問題:

  1. 指出檔案與相關行號。
  2. 說明違反的規則。
  3. 顯示簡短的修正前/後程式碼。

跳過沒有問題的檔案。最後以優先順序摘要列出最需要優先進行的變更。

輸出範例:

DataLoader.swift

第 18 行:Actor 可重入性——狀態可能在 await 之後改變。

// 修正前
actor Cache {
    var items: [String: Data] = [:]

    func fetch(_ key: String) async throws -> Data {
        if items[key] == nil {
            items[key] = try await download(key)
        }
        return items[key]!
    }
}

// 修正後
actor Cache {
    var items: [String: Data] = [:]

    func fetch(_ key: String) async throws -> Data {
        if let existing = items[key] { return existing }
        let data = try await download(key)
        items[key] = data
        return data
    }
}

第 34 行:應使用 withTaskGroup 而非在迴圈中建立任務。

// 修正前
for url in urls {
    Task { try await fetch(url) }
}

// 修正後
try await withThrowingTaskGroup(of: Data.self) { group in
    for url in urls {
        group.addTask { try await fetch(url) }
    }

    for try await result in group {
        process(result)
    }
}

摘要

  1. 正確性(高): 第 18 行的 actor 可重入性錯誤可能導致重複下載與強制解包崩潰。
  2. 結構(中): 第 34 行迴圈中的非結構化任務會失去取消傳播。

範例結束。

參考資料

  • references/hotspots.md - 程式碼審查的 grep 目標:已知危險模式及每種模式應檢查的項目。
  • references/new-features.md - Swift 6.2 的變更會影響審查建議:預設 actor 隔離、隔離的協定遵循、呼叫者-actor 非同步行為、@concurrentTask.immediate、任務命名與優先級提升。
  • references/actors.md - Actor 可重入性、共享狀態標註、全域 actor 推斷與隔離模式。
  • references/structured.md - 使用 task groups 取代迴圈、捨棄 task groups、並行限制。
  • references/unstructured.md - Task 與 Task.detached 的比較,何時 Task {} 是程式碼壞味道。
  • references/cancellation.md - 取消傳播、協作式檢查、中斷的取消模式。
  • references/async-streams.md - AsyncStream 工廠、continuation 生命週期、背壓。
  • references/bridging.md - Checked continuations、包裝舊版 API、@unchecked Sendable
  • references/interop.md - 從 GCD 遷移、Mutex/鎖、完成處理器、委派與 Combine。
  • references/bug-patterns.md - 常見的並行失敗模式及其修復方式。
  • references/diagnostics.md - Strict-concurrency 編譯器錯誤、協定遵循修復與可能的解決方案。
  • references/testing.md - 使用 Swift Testing 的非同步測試策略、競爭檢測、避免基於時間的測試。