Start learning free

LESSON 190 OF 678 · SWIFT ESSENTIALS

Protocols: a contract for capabilities

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:

error: type 'Dog' does not conform to protocol 'Describable'
note: protocol requires function 'describe()' with type '() -> String'; add a stub for conformance

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