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.

  1. What can live in a protocol? What can live in an extension? 1.3.1 · L1
    A protocol declares requirements: methods, properties (get/set), initializers, subscripts, associated types, and primary associated types. Since Swift 5.7 it…
  2. What is protocol-oriented programming, and when does it fail? 1.3.2 · L2
    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.

  1. Protocol extension vs inheritance for default behaviour — what are the tradeoffs? 1.3.3 · L3
    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…
  2. Why might collection.map call the stdlib generic overload instead of a protocol-extension map you wrote? 1.3.4 · L5
    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.

  1. What is an associated type? Why can’t you write let x: MyPAT easily? 1.3.5 · L2
    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…
  2. What is a primary associated type? Give an example. 1.3.6 · L3
    A primary associated type is declared in angle brackets after the protocol name: protocol Collection<Element>: Sequence That lets you constrain the existential…
  3. What is a type eraser (AnyHashable, AnyView, AnyCancellable)? When do you write one? 1.3.7 · L3
    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.

  1. How do you evolve a public protocol without breaking clients? 1.3.8 · L8
    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