1.3 · Protocols, extensions, associated types
Protocols are Swift’s primary abstraction tool — and the source of its most confusing silent bug: a method added in an extension is not a requirement, so it is statically dispatched.
Mental model. A protocol requirement gets a witness-table slot. A method that lives only in an extension does not. That single distinction explains dispatch, overriding, and type erasure.
Protocols and extensions
Requirements versus shared behaviour.
- What can live in a protocol? What can live in an extension?
A protocol declares requirements: methods, properties (get/set), initializers, subscripts, associated types, and primary associated types. Since Swift 5.7 it… - What is protocol-oriented programming, and when does it fail?
Model behaviour as small protocols plus extensions plus generics, instead of a deep class hierarchy. You get composition, retroactive conformance (conforming a…
Default behaviour and dispatch
Where extension methods quietly win or lose.
- Protocol extension vs inheritance for default behaviour — what are the tradeoffs?
An extension adds methods without adding a vtable or witness-table entry unless the method is also a protocol requirement. If it is only in the extension… - Why might
collection.mapcall the stdlib generic overload instead of a protocol-extensionmapyou wrote?
Overload resolution prefers the more specialized, statically-known candidate. The stdlib's map is generic over Sequence and gets specialized for Array; your…
Associated types and erasure
Protocols that are generic over something.
- What is an associated type? Why can’t you write
let x: MyPATeasily?
An associated type is a placeholder that the conforming type fills in, e.g. IteratorProtocol.Element. The protocol describes a family of types, not a single… - What is a primary associated type? Give an example.
A primary associated type is declared in angle brackets after the protocol name: protocol Collection<Element>: Sequence That lets you constrain the existential… - What is a type eraser (
AnyHashable,AnyView,AnyCancellable)? When do you write one?
A type eraser is a concrete wrapper that hides a generic or associated type behind a uniform surface: AnyHashable, AnyView, AnyPublisher, AnyCancellable…
Evolving a protocol
Changing a public contract without breaking clients.
- How do you evolve a public protocol without breaking clients?
Prefer additive change: a new protocol, a new requirement with a default implementation, or an @available-gated requirement. Adding a requirement without a…
More in Swift language
- 1.1 · Value vs reference types
- 1.2 · Optionals, pattern matching, control flow
- 1.4 · Generics, <code>some</code>, <code>any</code>
- 1.5 · Closures, escaping, capture lists
- 1.6 · Properties, observers, wrappers
- 1.7 · Access control
- 1.8 · Error handling, <code>defer</code>, ownership
- 1.9 · Strings and Unicode
- 1.10 · Codable, Sendable, macros, ABI
- 1.11 · Static vs dynamic dispatch