Start learning free

LESSON 154 OF 349 · SWIFT ESSENTIALS

Protocols: a contract for capabilities in Swift

Lesson

So far, every type you've used — Int, String, your own structs — stood alone. A protocol lets you describe a capability that many unrelated types can share. It's a contract: it lists WHAT a conforming type must provide, and writes no bodies at all:

protocol Describable {
    func describe() -> String
}

Any type can sign the contract by putting : Describable after its name and implementing every requirement:

struct Dog: Describable {
    func describe() -> String { return "Dog named Rex" }
}

Once a type conforms, the protocol itself can be used as a type. An array of [any Describable] happily mixes a Dog and a City — two types with no ancestor in common — because each one guarantees it knows how to describe() itself. When you call item.describe() in a loop, Swift picks the right implementation for whichever concrete type is really there. One interface, many behaviors.


The trap:

The contract is not a suggestion. Write : Describable and then "forget" the method:

struct Dog: Describable {
}

...and the compiler refuses to build your program:

trap.swift:4:8: error: type 'Dog' does not conform to protocol 'Describable'
1 | protocol Describable {
2 |     func describe() -> String
  |          `- note: protocol requires function 'describe()' with type '() -> String'; add a stub for conformance
3 | }
4 | struct Dog: Describable {
  |        `- error: type 'Dog' does not conform to protocol 'Describable'
5 | }

Read it bottom-up: the error says which type broke its promise, and the note points at the exact requirement that's missing. Implement describe() with the exact same name, parameters and return type, and the error disappears. This strictness is the feature: if it compiles, every element of [any Describable] is guaranteed to answer describe().


Assignment
Follow the Coding Tutorial and put one protocol in charge of two unrelated types:

  • declare a protocol Describable requiring func describe() -> String,
  • make struct Dog conform, returning "Dog named Rex",
  • make struct City conform, returning "City of Paris",
  • put one of each into let items: [any Describable],
  • loop over items and print each element's describe().

The exact expected output is:

Dog named Rex
City of Paris

Hint
Inside the protocol, the method has no body — just its signature. Inside each struct, it must have a body. The loop variable's type is any Describable, and that's all the loop needs to know.


STEP 1 OF 9
    Ctrl + Enter to check

    Protocols Basics in Swift

    Keep going with SwiftAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free