Protocols
Prerequisites: Structs, Classes and reference types
A protocol describes a set of requirements — properties and methods — that a type promises to provide. Any struct, class, or enum can conform to a protocol by meeting those requirements.
Real-world analogy: a protocol is a job description ("must be able to drive, must have a license"). Anyone who meets it can do the job, whatever their background.
Example
protocol Shape {
var name: String { get }
func area() -> Double
}
struct Square: Shape {
let side: Double
let name = "Square"
func area() -> Double { side * side }
}
struct Circle: Shape {
let radius: Double
let name = "Circle"
func area() -> Double { 3.14 * radius * radius }
}
let shapes: [any Shape] = [Square(side: 2), Circle(radius: 1)]
for shape in shapes {
print("\(shape.name): \(shape.area())")
}
Expected output
Square: 4.0
Circle: 3.14
var name: String { get }requires a readablenameproperty — stored or computed, either works.struct Square: Shapedeclares conformance. IfSquarewere missingarea(), it wouldn't compile.[any Shape]is an array that can hold any type conforming toShape. (anyand its partnersomeare covered in Level 3.)
Standard protocols
Some of the most useful protocols come with Swift, and the compiler can implement them for you:
struct Version: Equatable, Hashable, Comparable, CustomStringConvertible {
let major: Int
let minor: Int
static func < (lhs: Version, rhs: Version) -> Bool {
(lhs.major, lhs.minor) < (rhs.major, rhs.minor)
}
var description: String { "\(major).\(minor)" }
}
let versions = [Version(major: 1, minor: 10), Version(major: 1, minor: 9)]
print(versions.sorted())
print(versions[0] == Version(major: 1, minor: 10))
print(Set(versions).count)
[1.9, 1.10]
true
2
Equatablegives==— generated automatically from the properties.Hashablelets the type be used in sets and as dictionary keys — also generated.Comparableneeds only<; you get>,<=,sorted(),max(), and more for free.CustomStringConvertiblecontrols howprintdisplays the value.
Common mistakes
- Missing a requirement:
type 'Square' does not conform to protocol 'Shape'. Xcode's fix-it can add stubs for the missing members. - Making protocols too big. Small, focused protocols are easier to conform to and combine.