Protocols & Extensions
A protocol defines a set of requirements — methods and properties a type promises to implement — without providing any implementation itself. Combined with extensions, which let you add functionality to a type after it's already defined (even a type you don't own, like Swift's own Int), this is how Swift shares behavior across unrelated types without deep class inheritance.
Defining and conforming to a protocol
protocol Describable { func describe() -> String } struct Product: Describable { let name: String let price: Double func describe() -> String { return "\(name): $\(price)" } } let item = Product(name: "Keyboard", price: 49.99) print(item.describe())
Keyboard: $49.99
Product: Describable is a promise: "this struct implements everything Describable requires." If Product were missing describe(), that would be a compile error, not something discovered later at runtime.
Protocols as types
struct Service: Describable { func describe() -> String { "A support service" } } let items: [Describable] = [ Product(name: "Mouse", price: 19.99), Service() ] for item in items { print(item.describe()) }
Mouse: $19.99 A support service
An array typed as [Describable] can hold completely unrelated types — a Product struct and a Service struct share no inheritance relationship at all — as long as each one conforms to the protocol.
Extensions: adding behavior to an existing type
extension Int { var isEven: Bool { return self % 2 == 0 } } print(4.isEven) print(7.isEven)
true false
This adds a computed property, isEven, directly onto Int — a type built into Swift itself that you can't edit the source of. Extensions are how Swift's own standard library keeps growing without ever needing you to subclass anything.