You can use a where clause which lets you specify as many requirements as you want (all of which must be fulfilled) separated by commas
func someFunc<T where T:SomeProtocol, T:SomeOtherProtocol>(arg: T) {
// stuff
}
func someFunc<T: SomeProtocol & SomeOtherProtocol>(arg: T) {
// stuff
}
or the more powerful where clause:
func someFunc<T>(arg: T) where T:SomeProtocol, T:SomeOtherProtocol{
// stuff
}
You can of course use protocol composition (e.g., protocol<SomeProtocol, SomeOtherProtocol>
), but it's a little less flexible.
Using where
lets you deal with cases where multiple types are involved.
You may still want to compose protocols for reuse in multiple places, or just to give the composed protocol a meaningful name.
func someFunc(arg: SomeProtocol & SomeOtherProtocol) {
// stuff
}
This feels more natural as the protocols are next to the argument.
You have two possibilities:
You use a where clause as indicated in Jiaaro's answer:
func someFunc<T where T : SomeProtocol, T : SomeOtherProtocol>(arg: T) {
// do stuff
}
You use a protocol composition type:
func someFunc<T : protocol<SomeProtocol, SomeOtherProtocol>>(arg: T) {
// do stuff
}
The evolution to Swift 3.0 brings some changes. Our two choices now look a little different.
Using a where
clause in Swift 3.0:
The where
clause has now moved to the end of a function signature to improve readability. So multiple protocol inheritance now looks like this:
func someFunc<T>(arg: T) where T:SomeProtocol, T:SomeOtherProtocol {
}
Using the protocol<>
construct in Swift 3.0:
Composition using the protocol<>
construct is being deprecated. The earlier protocol<SomeProtocol, SomeOtherProtocol>
now looks like this:
func someFunc<T:SomeProtocol & SomeOtherProtocol>(arg: T) {
}
References.
More info on the changes for where
are here: https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.md
And, more on the changes for the protocol<> construct are here: https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md
Swift 3 offers up to 3 different ways to declare your function.
protocol SomeProtocol {
/* ... */
}
protocol SomeOtherProtocol {
/* ... */
}
&
operatorfunc someFunc<T: SomeProtocol & SomeOtherProtocol>(arg: T) {
/* ... */
}
where
clausefunc someFunc<T>(arg: T) where T: SomeProtocol, T: SomeOtherProtocol {
/* ... */
}
where
clause and &
operatorfunc someFunc<T>(arg: T) where T: SomeProtocol & SomeOtherProtocol {
/* ... */
}
Also note that you can use typealias
in order to shorten your function declaration.
typealias RequiredProtocols = SomeProtocol & SomeOtherProtocol
func someFunc<T: RequiredProtocols>(arg: T) {
/* ... */
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With