Protocol Composition
Protocol composition lets you say a type must check off items from more than one checklist at the same time, combining them with an ampersand.
Syntax
func functionName(_ param: ProtocolA & ProtocolB) {
// param has members of both protocols
}
func other(_ param: ProtocolA & ProtocolB & ProtocolC) { }
Requiring Multiple Protocols with &
A function parameter typed as ProtocolA & ProtocolB accepts only values conforming to both protocols simultaneously.
Example: Requiring Multiple Protocols with &
// Define a protocol `Named` describing required behavior
protocol Named {
var name: String { get }
}
// Define a protocol `Aged` describing required behavior
protocol Aged {
var age: Int { get }
}
// Define a struct `Person`
struct Person: Named, Aged {
var name: String
var age: Int
}
// Define the function `describe` taking `value` and returning a String
func describe(_ value: Named & Aged) -> String {
// Return `"\(value.name) is \(value.age) years old"` from this function
return "\(value.name) is \(value.age) years old"
}
// Declare a constant `person`, set to `Person(name: "Lee", age: 40)`
let person = Person(name: "Lee", age: 40)
// Print `describe(person)` to the console
print(describe(person))
Login to try C/C++/Java/PHP code in the editor
Composition with Three or More Protocols
Protocol composition isn't limited to two protocols -- any number can be combined with additional & operators.
Example: Composition with Three or More Protocols
// Define a protocol `Named` describing required behavior
protocol Named { var name: String { get } }
// Define a protocol `Aged` describing required behavior
protocol Aged { var age: Int { get } }
// Define a protocol `Employed` describing required behavior
protocol Employed { var job: String { get } }
// Define a struct `Worker`
struct Worker: Named, Aged, Employed {
var name: String
var age: Int
var job: String
}
// Define the function `introduce` taking `value`
func introduce(_ value: Named & Aged & Employed) {
// Print "\(value.name), \(value.age), works as \(value.job)" to the console
print("\(value.name), \(value.age), works as \(value.job)")
}
introduce(Worker(name: "Kai", age: 33, job: "Engineer"))
Login to try C/C++/Java/PHP code in the editor
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the
view already swaps in the hi_ translation fields (or blanks these
out if untranslated), so this renders correctly for both languages
without a lang_code check here. #}
Common Mistakes
- Trying to use inheritance-style syntax to require multiple protocols; composition uses
&between protocol names, not commas in a type annotation. - Forgetting a composed type (
ProtocolA & ProtocolB) requires an instance to conform to BOTH protocols, not just one of them. - Overcomplicating a function signature with many composed protocols when a single custom protocol combining the requirements would be clearer.
Chapter Summary
ProtocolA & ProtocolBdescribes a type conforming to both protocols at once.- This is commonly used as a parameter type to require multiple capabilities.
- Composition differs from class inheritance, which only allows one superclass.
- You can compose any number of protocols together with
&.
🔒
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: