I was recently reading Protocols, Generic Type Constraints and Arrays in Swift. My question concerns the following two examples from the blog:
The code:
protocol MyProtocol1 {
var myValue: Self { get }
}
let array: [MyProtocol1] = [] // Error.
Produces the error:
Protocol 'MyProtocol1' can only be used as a generic constraint because it has Self or associated type requirements.
That's expected and there have been several SO questions concerning the topic. However, by changing myValue
to a function there's no longer any error, yet in both cases Self
is returned.
protocol MyProtocol2 {
func myValue() -> Self
}
let array: [MyProtocol2] = [] // This is okay.
Does anyone know the cause of this seemingly strange behaviour?
A protocol defines a blueprint of methods, properties, and other requirements. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. But there would be a time when you want to restrict protocols to be adopted by a specific class.
In Swift, a protocol defines a blueprint of methods or properties that can then be adopted by classes (or any other types).
It's explained about 18 minutes into this video: https://developer.apple.com/videos/wwdc/2015/?id=408
Because your protocol references "self" it can only be used as a generic constraint not as a type.
Example: Let's say 2 structs implement your protocol - Duke & Silver.
If you made an array of protocol2 ([protocol2]), then your array could contain either Dukes are Silvers.
myValue specifically states that the return value must be self. This means that a Duke must return a Duke and a Silver must return a Silver. As such, you can't have Dukes & Silvers in the same array because their MyValue functions have different return values.
To fix the issue, you can either:
1) Make the return type of myValue protocol2 so that Dukes and Silvers both just return a protocol2 type
2) Make an array of generics that conform to protocol2
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