swift

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Swift

Swift

Modern Swift development with protocol-oriented programming and async/await.
基于协议导向编程和async/await的现代Swift开发。

When to Use

适用场景

  • Working with
    .swift
    files
  • Building iOS/macOS applications
  • SwiftUI development
  • Server-side Swift with Vapor
  • 处理.swift文件
  • 构建iOS/macOS应用
  • SwiftUI开发
  • 使用Vapor进行Swift服务端开发

Quick Start

快速开始

swift
struct User: Identifiable, Codable {
    let id: UUID
    var name: String
    var email: String

    var displayName: String {
        name.capitalized
    }
}
swift
struct User: Identifiable, Codable {
    let id: UUID
    var name: String
    var email: String

    var displayName: String {
        name.capitalized
    }
}

Core Concepts

核心概念

Value Types & Structs

值类型与结构体

swift
// Prefer structs for data
struct User: Identifiable, Codable, Hashable {
    let id: UUID
    var name: String
    var email: String
    var createdAt: Date = .now
}

// Enums with associated values
enum NetworkError: Error, LocalizedError {
    case invalidURL
    case noData
    case decodingError(Error)

    var errorDescription: String? {
        switch self {
        case .invalidURL: return "Invalid URL"
        case .noData: return "No data received"
        case .decodingError(let error): return "Decoding failed: \(error)"
        }
    }
}
swift
// 优先使用结构体存储数据
struct User: Identifiable, Codable, Hashable {
    let id: UUID
    var name: String
    var email: String
    var createdAt: Date = .now
}

// 带关联值的枚举
enum NetworkError: Error, LocalizedError {
    case invalidURL
    case noData
    case decodingError(Error)

    var errorDescription: String? {
        switch self {
        case .invalidURL: return "Invalid URL"
        case .noData: return "No data received"
        case .decodingError(let error): return "Decoding failed: \(error)"
        }
    }
}

Protocol-Oriented Programming

协议导向编程

swift
protocol Repository {
    associatedtype Entity: Identifiable

    func findById(_ id: Entity.ID) async throws -> Entity?
    func save(_ entity: Entity) async throws -> Entity
    func delete(_ entity: Entity) async throws
}

extension Repository {
    func saveAll(_ entities: [Entity]) async throws -> [Entity] {
        try await withThrowingTaskGroup(of: Entity.self) { group in
            for entity in entities {
                group.addTask { try await self.save(entity) }
            }
            return try await group.reduce(into: []) { $0.append($1) }
        }
    }
}
swift
protocol Repository {
    associatedtype Entity: Identifiable

    func findById(_ id: Entity.ID) async throws -> Entity?
    func save(_ entity: Entity) async throws -> Entity
    func delete(_ entity: Entity) async throws
}

extension Repository {
    func saveAll(_ entities: [Entity]) async throws -> [Entity] {
        try await withThrowingTaskGroup(of: Entity.self) { group in
            for entity in entities {
                group.addTask { try await self.save(entity) }
            }
            return try await group.reduce(into: []) { $0.append($1) }
        }
    }
}

Common Patterns

常见模式

Async/Await

Async/Await

swift
func fetchUser(id: UUID) async throws -> User {
    let url = URL(string: "https://api.example.com/users/\(id)")!
    let (data, response) = try await URLSession.shared.data(from: url)

    guard let httpResponse = response as? HTTPURLResponse,
          httpResponse.statusCode == 200 else {
        throw NetworkError.invalidResponse
    }

    return try JSONDecoder().decode(User.self, from: data)
}

// Parallel execution
async let user = fetchUser(id: userId)
async let orders = fetchOrders(userId: userId)
let (userResult, ordersResult) = try await (user, orders)
swift
func fetchUser(id: UUID) async throws -> User {
    let url = URL(string: "https://api.example.com/users/\(id)")!
    let (data, response) = try await URLSession.shared.data(from: url)

    guard let httpResponse = response as? HTTPURLResponse,
          httpResponse.statusCode == 200 else {
        throw NetworkError.invalidResponse
    }

    return try JSONDecoder().decode(User.self, from: data)
}

// 并行执行
async let user = fetchUser(id: userId)
async let orders = fetchOrders(userId: userId)
let (userResult, ordersResult) = try await (user, orders)

Actors

Actors

swift
actor UserCache {
    private var cache: [UUID: User] = [:]

    func get(_ id: UUID) -> User? { cache[id] }
    func set(_ user: User) { cache[user.id] = user }
}
swift
actor UserCache {
    private var cache: [UUID: User] = [:]

    func get(_ id: UUID) -> User? { cache[id] }
    func set(_ user: User) { cache[user.id] = user }
}

Best Practices

最佳实践

Do:
  • Prefer value types (structs, enums) over classes
  • Use protocol-oriented programming
  • Handle optionals safely with
    if let
    ,
    guard
  • Use async/await for concurrency
Don't:
  • Force unwrap with
    !
    except for IBOutlets
  • Use implicitly unwrapped optionals unnecessarily
  • Ignore error handling
  • Create reference cycles without
    weak
    /
    unowned
推荐做法:
  • 优先使用值类型(结构体、枚举)而非类
  • 采用协议导向编程
  • 使用
    if let
    guard
    安全处理可选类型
  • 使用async/await实现并发
不推荐做法:
  • 除IBOutlets外,避免使用
    !
    强制解包
  • 避免不必要地使用隐式解包可选类型
  • 不要忽略错误处理
  • 若不使用
    weak
    /
    unowned
    ,避免创建引用循环

Troubleshooting

问题排查

ErrorCauseSolution
unexpectedly found nil
Force unwrap of nilUse optional binding
Actor-isolated property
Accessing actor from sync contextUse
await
Sendable closure
Non-sendable type across concurrencyMake type Sendable
错误信息原因解决方案
unexpectedly found nil
对nil进行强制解包使用可选绑定
Actor-isolated property
从同步上下文访问actor使用
await
Sendable closure
并发场景下使用非Sendable类型将类型标记为Sendable

References

参考资料