问题
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?
回答1:
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
回答2:
I do not have definitive answer to this but I feel this may be due to class size and internal layout.
Having a associated type or Self type member will affect the size of object and hence the array size, but using Self as method return type will affect the object size.
来源:https://stackoverflow.com/questions/30077159/behaviour-of-protocols-with-self