Swift Protocol Extensions
A protocol extension is an extension of a protocol itself. It gives every conforming type a default implementation of a method.
A default greet method
The Greeter protocol requires a name property and a greet method. The extension builds the default greet method from that required name.
protocol Greeter {
var name: String { get }
func greet() -> String
}
extension Greeter {
func greet() -> String {
return "Hello, \(name)"
}
}
struct Person: Greeter {
var name: String
}
let person = Person(name: "Ana")
print(person.greet())One type overrides the default
The Person type uses the default greet method from the extension. The Robot type writes its own greet method, and that version runs instead.
protocol Greeter {
var name: String { get }
func greet() -> String
}
extension Greeter {
func greet() -> String {
return "Hello, \(name)"
}
}
struct Person: Greeter {
var name: String
}
struct Robot: Greeter {
var name: String
func greet() -> String {
return "Beep, \(name)"
}
}
let person = Person(name: "Ana")
let robot = Robot(name: "R2")
print(person.greet())
print(robot.greet())A default built on a required price
The Priced protocol requires a price property and a priceTag method. The extension builds the default priceTag from the price, and the Ticket type uses it unchanged.
protocol Priced {
var price: Int { get }
func priceTag() -> String
}
extension Priced {
func priceTag() -> String {
return "Price: \(price) coins"
}
}
struct Ticket: Priced {
var price: Int
}
let ticket = Ticket(price: 15)
print(ticket.priceTag())Example
protocol Speaker {
var sound: String { get }
func speak() -> String
}
extension Speaker {
func speak() -> String {
return "It says \(sound)"
}
}
struct Dog: Speaker {
var sound: String
}
struct Cat: Speaker {
var sound: String
func speak() -> String {
return "Quietly, \(sound)"
}
}
let dog = Dog(sound: "woof")
let cat = Cat(sound: "mew")
print(dog.speak())
print(cat.speak())Key points
- A protocol extension is written by extending the protocol name.
- A method written inside the extension becomes the default implementation for the protocol.
- The default implementation can read the properties that the protocol requires.
- A conforming type that writes no version of the method uses the default implementation.
- A conforming type that writes its own version of the method uses that version instead.
In this example, the Speaker protocol requires a sound property and a speak method, and its extension gives speak a default built from sound. The Dog type uses the default and prints It says woof. The Cat type writes its own speak method, so its print shows Quietly, mew instead.
Note
The protocol still lists the method as a requirement, so every conforming type is guaranteed to answer the call.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
A conforming type writes no version of a method that a protocol extension implements. Which implementation runs?