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.