coding-standards-enforcer

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Coding Standards Enforcer

编码标准强制执行工具

Description and Goals

描述与目标

This skill enforces repository-wide coding standards for Swift 6.2 concurrency, Swift language rules, and best practices. It ensures all Swift code in the repository follows consistent patterns, uses modern Swift APIs, and adheres to strict concurrency requirements.
本技能用于在仓库范围内强制执行Swift 6.2并发机制、Swift语言规则及最佳实践的编码标准。确保仓库中所有Swift代码遵循一致的模式,使用现代Swift API,并符合严格的并发要求。

Goals

目标

  • Ensure compliance with Swift 6.2 strict concurrency rules
  • Enforce modern Swift language patterns and APIs
  • Prevent common concurrency mistakes and anti-patterns
  • Maintain consistent code style across the repository
  • Support Swift 6 migration and best practices
  • 确保符合Swift 6.2严格并发规则
  • 推行现代Swift语言模式与API
  • 预防常见的并发错误与反模式
  • 维护仓库内代码风格的一致性
  • 支持Swift 6迁移及最佳实践

What This Skill Should Do

本技能的适用场景

When reviewing or implementing Swift code changes, this skill should:
  1. Enforce concurrency rules - Ensure all code follows Swift 6.2 strict concurrency requirements
  2. Check language standards - Verify use of modern Swift APIs and patterns
  3. Identify violations - Scan for common mistakes and anti-patterns
  4. Suggest fixes - Provide guidance on how to correct violations
  5. Maintain consistency - Ensure code follows repository-wide standards
Use this skill whenever you add, modify, or review Swift code in this repo.
在审查或实现Swift代码变更时,本技能应:
  1. 强制执行并发规则 - 确保所有代码遵循Swift 6.2严格并发要求
  2. 检查语言标准 - 验证是否使用现代Swift API与模式
  3. 识别违规情况 - 扫描常见错误与反模式
  4. 提供修复建议 - 指导如何修正违规问题
  5. 保持一致性 - 确保代码符合仓库范围内的标准
每当你在本仓库中添加、修改或审查Swift代码时,都应使用本技能。

Information About the Skill

技能相关信息

Workflow

工作流程

  1. Identify the files and changes in scope.
  2. Scan for violations of the rules below.
  3. Apply fixes or call out deviations explicitly.
  1. 确定涉及的文件与变更范围。
  2. 扫描是否存在以下规则的违规情况。
  3. 应用修复或明确指出偏差。

Swift Concurrency Guidelines

Swift并发指南

Core Mental Model

核心思维模型

Think in isolation domains rather than threads:
  • MainActor
    is the UI lane and must own UI state.
  • actor
    types protect their own mutable state.
  • nonisolated
    code is shared and cannot touch actor state.
  • Sendable
    types are safe to move across domains.
以隔离域而非线程的角度思考:
  • MainActor
    是UI专用通道,必须拥有UI状态。
  • actor
    类型保护自身的可变状态。
  • nonisolated
    代码是共享的,不能访问actor状态。
  • Sendable
    类型可安全跨域传递。

Strict Concurrency

严格并发

Swift 6.2 defaults to
@MainActor
isolation for Views and UI logic. Assume strict isolation checks are active. Everything is
@MainActor
by default.
Swift 6.2默认对视图和UI逻辑采用
@MainActor
隔离。假设严格隔离检查已启用,所有内容默认均为
@MainActor

Async and Parallel Work

异步与并行工作

swift
func fetchUser(id: Int) async throws -> User {
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

async let avatar = fetchImage("avatar.jpg")
async let banner = fetchImage("banner.jpg")
let profile = Profile(avatar: try await avatar, banner: try await banner)
swift
func fetchUser(id: Int) async throws -> User {
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

async let avatar = fetchImage("avatar.jpg")
async let banner = fetchImage("banner.jpg")
let profile = Profile(avatar: try await avatar, banner: try await banner)

Tasks and Task Groups

任务与任务组

swift
.task { avatar = await downloadAvatar() }

Task { await saveProfile() }

try await withThrowingTaskGroup(of: Void.self) { group in
    group.addTask { avatar = try await downloadAvatar() }
    group.addTask { bio = try await fetchBio() }
    try await group.waitForAll()
}
swift
.task { avatar = await downloadAvatar() }

Task { await saveProfile() }

try await withThrowingTaskGroup(of: Void.self) { group in
    group.addTask { avatar = try await downloadAvatar() }
    group.addTask { bio = try await fetchBio() }
    try await group.waitForAll()
}

Isolation Domains

隔离域

swift
@MainActor
final class ViewModel {
    var items: [Item] = []
}

actor BankAccount {
    var balance: Double = 0
    func deposit(_ amount: Double) { balance += amount }
}
swift
@MainActor
final class ViewModel {
    var items: [Item] = []
}

actor BankAccount {
    var balance: Double = 0
    func deposit(_ amount: Double) { balance += amount }
}

Approachable Concurrency Settings (Swift 6.2+)

易用并发设置(Swift 6.2+)

  • SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor
    keeps UI code on the main actor by default.
  • SWIFT_APPROACHABLE_CONCURRENCY = YES
    keeps nonisolated async on the caller's actor.
swift
@concurrent func processLargeFile() async { }
  • SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor
    使UI代码默认在主actor上运行。
  • SWIFT_APPROACHABLE_CONCURRENCY = YES
    使非隔离异步代码在调用者的actor上运行。
swift
@concurrent func processLargeFile() async { }

Sendable

Sendable类型

swift
struct User: Sendable {
    let id: Int
    let name: String
}

final class ThreadSafeCache: @unchecked Sendable {
    private let lock = NSLock()
    private var storage: [String: Data] = [:]
}
swift
struct User: Sendable {
    let id: Int
    let name: String
}

final class ThreadSafeCache: @unchecked Sendable {
    private let lock = NSLock()
    private var storage: [String: Data] = [:]
}

Isolation Inheritance

隔离继承

  • Task { }
    inherits the current actor.
  • Task.detached { }
    does not inherit isolation and should be rare.
  • Task { }
    继承当前actor。
  • Task.detached { }
    不继承隔离,应尽量少用。

Background Tasks

后台任务

Move heavy physics/data work off the main actor using
@concurrent
functions or dedicated actors.
使用
@concurrent
函数或专用actor将繁重的物理/数据处理工作移出主actor。

Task Management

任务管理

Cancel long-running tasks on teardown.
在销毁时取消长时间运行的任务。

Common Mistakes to Avoid

需避免的常见错误

  • Treating
    async
    as automatic background work.
  • Creating many actors when
    @MainActor
    is sufficient.
  • Using
    MainActor.run
    when the enclosing function can be annotated.
  • Blocking async code with
    DispatchSemaphore
    or
    DispatchGroup.wait()
    .
  • Spawning unstructured
    Task
    instances instead of
    async let
    or task groups.
  • async
    视为自动后台工作。
  • @MainActor
    足够的情况下创建大量actor。
  • 在封闭函数可添加注解时使用
    MainActor.run
  • 使用
    DispatchSemaphore
    DispatchGroup.wait()
    阻塞异步代码。
  • 生成非结构化
    Task
    实例而非使用
    async let
    或任务组。

Quick Reference

快速参考

  • async
    and
    await
    for suspension points.
  • Task { }
    for structured async work.
  • actor
    for isolated mutable state.
  • Sendable
    for cross-actor data transfer.
  • async
    await
    用于挂起点。
  • Task { }
    用于结构化异步工作。
  • actor
    用于隔离可变状态。
  • Sendable
    用于跨actor数据传输。

Swift Language Standards

Swift语言标准

Observable Classes

可观察类

@Observable
classes are
@MainActor
by default, so explicit
@MainActor
annotation is not needed and should always be removed.
@Observable
类默认是
@MainActor
,因此无需显式添加
@MainActor
注解,且应始终移除该注解。

Observation vs Combine

观察机制 vs Combine

  • Prefer
    @Observable
    +
    @State
    for reference-type models.
  • Avoid
    ObservableObject
    ,
    @StateObject
    , and
    @ObservedObject
    unless interacting with legacy code that still requires Combine.
  • 优先为引用类型模型使用
    @Observable
    +
    @State
  • 除非与仍需使用Combine的遗留代码交互,否则应避免使用
    ObservableObject
    @StateObject
    @ObservedObject

Swift-Native APIs

Swift原生API

Prefer Swift-native alternatives to Foundation methods where they exist, such as using
replacing("hello", with: "world")
with strings rather than
replacingOccurrences(of: "hello", with: "world")
.
在有替代方案的情况下,优先使用Swift原生API而非Foundation方法,例如对字符串使用
replacing("hello", with: "world")
而非
replacingOccurrences(of: "hello", with: "world")

Modern Foundation API

现代Foundation API

Prefer modern Foundation API, for example
URL.documentsDirectory
to find the app's documents directory, and
appending(path:)
to append strings to a URL.
优先使用现代Foundation API,例如使用
URL.documentsDirectory
查找应用的文档目录,使用
appending(path:)
将字符串追加到URL。

Number Formatting

数字格式化

Never use C-style number formatting such as
Text(String(format: "%.2f", abs(myNumber)))
; always use
Text(abs(change), format: .number.precision(.fractionLength(2)))
instead.
绝不要使用C风格的数字格式化,如
Text(String(format: "%.2f", abs(myNumber)))
;应始终使用
Text(abs(change), format: .number.precision(.fractionLength(2)))
替代。

Static Member Lookup

静态成员查找

Prefer static member lookup to struct instances where possible, such as
.circle
rather than
Circle()
, and
.borderedProminent
rather than
BorderedProminentButtonStyle()
.
尽可能优先使用静态成员查找而非结构体实例,例如使用
.circle
而非
Circle()
,使用
.borderedProminent
而非
BorderedProminentButtonStyle()

Modern Concurrency

现代并发机制

Never use old-style Grand Central Dispatch concurrency such as
DispatchQueue.main.async()
. If behavior like this is needed, always use modern Swift concurrency.
绝不要使用旧式Grand Central Dispatch并发机制,如
DispatchQueue.main.async()
。如果需要类似行为,应始终使用现代Swift并发机制。

Text Filtering

文本过滤

Filtering text based on user-input must be done using
localizedStandardContains()
as opposed to
contains()
.
基于用户输入的文本过滤必须使用
localizedStandardContains()
而非
contains()

Force Unwraps

强制解包

Avoid force unwraps and force
try
unless it is unrecoverable.
除非是不可恢复的情况,否则应避免强制解包和强制
try