Skip to content
AgileLogics
6 min read

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 readable name property — stored or computed, either works.
  • struct Square: Shape declares conformance. If Square were missing area(), it wouldn't compile.
  • [any Shape] is an array that can hold any type conforming to Shape. (any and its partner some are 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
  • Equatable gives == — generated automatically from the properties.
  • Hashable lets the type be used in sets and as dictionary keys — also generated.
  • Comparable needs only <; you get >, <=, sorted(), max(), and more for free.
  • CustomStringConvertible controls how print displays 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.