Swift: Multiple protocols in generic functions and elsewhere

Swift's algorithms typically restrict themselves to a single protocol for each generic type they employ. It is possible, however, to use more than one protocol inside your own generic functions, if you wish. But you must use the following syntax to do so:
func multiProtocol<T:protocol<MutableCollectionType, Printable>>(t:T) {

}
It is the keyword protocol that does the magic along with its angle brackets. These brackets enable the grouping together of protocols.

Going further

Looking at other scenarios, where a generic syntax isn't employed, it is also possible to substitute a Protocol where we'd normally place a Type and to do so in the multiple style outlined above. But we cannot in these instances use Swift protocols that have references to self within their methods. This means in short that this wouldn't work:
func multiProtocol(t:protocol<MutableCollectionType, Printable>) {
} // error
But if we were to require Printable and BooleanType, this would be fine
func multiProtocol(t:protocol<BooleanType, Printable>) {
} // OK
because neither of the latter pair have references to self in their method requirements or within the method requirements of the protocols from which they inherit.

Homemade protocols

With homemade protocols this rule about self not being allowed within protocol methods is likewise applied. So while the following is allowed
protocol Hello {
    
}

protocol World: class {
    
}
func multiProtocol(t:protocol<Hello, World>) {

}

class MyClass:Hello,World {
    
}

multiProtocol(MyClass()) // OK
if we were to add the following to the World protocol
protocol World {
func isRound(t: Self) -> Bool
}
then our multiProtocol() function would no longer be able to utilise this protocol. If we wanted to reinstate the requirement of this newly updated World protocol, then we'd need to translate the function into a generic syntax.

Outside of functions and methods

When building classes, structs and enums the approach is much simpler to remember. It is necessary only to list protocols one after another, as in this code extract from the example above:
class MyClass:Hello,World {
    
}
And finally there's one extra trick to mention. You'll notice the use of the word class in the "World" protocol above:
protocol World: class {
    
}
This means that it can only be adopted by classes and not structs or enums, but it must be placed after the colon and before any protocols being inherited by the protocol. See Apple docs (under the heading of "Class-only Protocols").
Endorse on Coderwall

Comments