Defining

A protocol declaration lists the methods, properties, and associated types a conforming type must provide.

Required methods

protocol Printable { func toString() -> String }

Any type that conforms to Printable must provide a toString() method with that exact signature. The protocol body holds only the signatures — no implementations.

Required properties

protocol Named { var name: String { get } }

{ get } declares a read-only requirement — the conforming type can satisfy it with a stored field, a computed variable, or anything else that produces a String when read. { get set } requires it to be writable too.

Multiple requirements

protocol Comparable: Equatable { func compare(other: Self) -> Ordering }

Self inside a protocol means "the type that ends up conforming." Comparable.compare on Int takes another Int; on String, another String. Comparable refines Equatable, so conformers also owe isEqual(to:).

Mutating requirements

If a method needs to mutate the conforming value, mark it mutating:

protocol Counter { mutating func increment() func current() -> Int }

A struct conforming to Counter will provide increment as a mutating func.

Static requirements

Protocols can require static methods too — useful for factories and "default value" patterns:

protocol Defaultable { init() }

Associated types

Sometimes the protocol depends on a type the conforming type chooses. That's an associated type:

protocol Container { type Item func count() -> Int func item(at index: Int) -> Item }

Array[T] conforms to Container with Item = T; a Stack[U] conforms with Item = U. Each conformance picks the concrete type. See Generics → Associated Types for the full story.