Protocol Extensions: Default Behavior for Free
Protocol extensions give conforming types default functionality "for free," like a standard toolkit with every blueprint. Use them to add common behavior to your protocols or even extend system types.
WHY IT EXISTS: Protocols define a contract of methods and properties, but they don't provide the actual code. Before protocol extensions, every single type conforming to a protocol had to write its own implementation for every requirement, leading to significant code duplication for common functionality.
THE MENTAL MODEL: Think of a protocol as a blueprint for a car, specifying it must have an engine and wheels. A protocol extension is like a factory-standard engine and a set of all-season tires that come with the blueprint. Any car model built from this blueprint gets these standard parts automatically. A custom sports car model can still choose to install its own high-performance engine, which would be used instead of the standard one.
HOW IT WORKS: You declare an extension on a protocol itself, like extension MyProtocol { ... }. Inside this block, you can write concrete implementations for the methods or computed properties defined in the protocol's requirements. Any type that conforms to MyProtocol now automatically has access to these default implementations. If the conforming type provides its own implementation for a method, the type's specific version is called at runtime, overriding the default.
WHEN TO USE IT: Protocol extensions are a cornerstone of Protocol-Oriented Programming in Swift. Use them to: first, provide default behavior for your own protocols, drastically reducing boilerplate for conforming types. Second, add new functionality to existing protocols, including standard library types like Collection or Codable. For example, you could add a helper method to all Encodable types that returns their JSON Data representation.
WHEN NOT TO USE IT: Do not use a protocol extension to add new requirements to a protocol; extensions are for adding behavior, while the protocol definition itself is for defining the contract. You also cannot add stored properties in an extension; only computed properties are allowed. Be cautious with methods defined only in the extension (not in the protocol requirements), as their dispatch behavior can lead to unexpected results.
ONE CANONICAL EXAMPLE: A powerful use is extending Swift's Collection protocol to add functionality to all arrays, sets, and dictionaries. For example, you can add a method to get a safe element at an index, returning nil if the index is out of bounds. extension Collection { subscript(safe index: Index) -> Element? { return indices.contains(index) ? self[index] : nil } } Now any array, like let letters = ["a", "b"], can safely access an element with letters[safe: 2], which returns nil instead of crashing.
Read the original → docs.swift.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.