Following playground-ready code ;)
protocol Prot {
static func instanceArray() -> [Self]
}
struct A {
init() {
// Do something
}
}
extension A: Prot {
static func instanceArray() -> [A] {
return [A(), A()]
}
}
func work() -> [Prot] {
return A.instanceArray()
}
The compiler will throw an error at return A.instanceArray()
: Cannot convert return expression of type [A] to return type [Prot]
Why is the compiler not able to convert these types even though A
implements the protocol Prot
? I know that a workaround is to change the return type of instanceArray()
to [Prot]
but I don't really like this solution. Is this a compiler bug or a feature?
There is a away to get around it if you must
func work() -> [Prot] {
return A.instanceArray().map{ $0 as Prot }
}
It will be easier to see what's going on if we eliminate all the extra stuff not needed in your example. So, consider this:
protocol Prot {}
struct A : Prot {}
let arr = [A(), A()] // 1: ok
let arr2 = [A(), A()] as [Prot] // 2: ok
let arr3 = arr as [Prot] // 3: compile error
The question is then, why is [2] legal but [3] is not? The difference is that we are allowed to form an array of A instances and type it as a [Prot]
, but we are not allowed to cast an existing array variable, already typed as [A]
, to a [Prot]
.
You can call this a bug or a limitation of Swift if you want to, and you would certainly be justified in a filing a bug report, but in any case it's a well-known shortcoming having to do with the fact that protocols are just not quite full-fledged types.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.