Community
Swift 5.10 Language Patterns
Swift patterns including value types, protocol-oriented design, concurrency, and Result builders.
CLAUDE.md
# Swift 5.10 Language Patterns
You are an expert in Swift with deep knowledge of the type system, concurrency model, and Apple platform best practices.
Value Types & Immutability:
- Prefer struct over class — value semantics prevent shared mutable state bugs
- Use let (constant) by default; only use var when mutation is required
- Structs are stack-allocated (faster), classes are heap-allocated (reference counted)
- Use class only when identity matters or inheritance is required
- Use enum for algebraic data types: enum Result<T> { case success(T); case failure(Error) }
Protocol-Oriented Design:
- Prefer protocols over class inheritance: protocol Drawable { func draw() }
- Use protocol extensions for default implementations
- Use associated types for generic protocols: protocol Container { associatedtype Item }
- Use some keyword for opaque return types: func makeShape() -> some Shape
- Use any keyword for existential types: func process(shapes: [any Shape])
- Prefer composition: conform to multiple protocols instead of deep inheritance
Swift Concurrency (async/await):
- Use async/await for asynchronous code — no completion handlers
- Use Task { } for launching concurrent work from synchronous contexts
- Use TaskGroup for structured concurrent operations with child tasks
- Use AsyncSequence and AsyncStream for asynchronous iteration
- Mark actor types for thread-safe mutable state: actor BankAccount { var balance: Int }
Actors & Data Isolation:
- Use actor for mutable state that needs thread safety
- Actor methods are implicitly async when called from outside
- Use @Sendable for closures that cross concurrency boundaries
- Use @MainActor for code that must run on the main thread (UI updates)
- Swift 5.10 strict concurrency checking: enable and fix all warnings
Error Handling:
- Use throws for recoverable errors: func parse() throws -> Document
- Use typed throws (Swift 5.10): func load() throws(NetworkError)
- Use do/catch with pattern matching: catch NetworkError.timeout { retry() }
- Use try? for optional conversion (nil on error)
- Use guard let for early returns: guard let user = getUser() else { return }
- Use Result<T, E> for async callbacks that can't use throws
Optionals:
- Use optional chaining: user?.address?.city
- Use nil coalescing: let name = user?.name ?? "Anonymous"
- Use if let / guard let for safe unwrapping — NEVER force-unwrap (!) in production
- Use map/flatMap on optionals for transformations without unwrapping
Add to your project root CLAUDE.md file, or append to an existing one.