Swift has no built-in behavior for speculatively converting the contents of arrays from one arbitrary type to another. He will do this only for two types, which, as he knows, have a subtype / supertype relationship:
class A { } class B: A { } let a: [A] = [B(),B()]
The protocol does not help:
protocol P { } struct S1: P { } struct S2: P { } let a = [S1(),S1()]
Your example is basically a variant of this latter. You have an array of type [T] , and you want to pass it to [MyType] . It is important to understand that you do not have an array of type [MyProtocol] . Your generic type T is the specific type that MyProtocol should implement, but it is not the same.
To find out why you cannot just use any type for any other type, try this code:
protocol P { } struct S: P { } let a: [P] = [S(),S()] let b = a as? [S]
This will result in a runtime error: "fatal error: BitCast between types of different sizes cannot be insecure." This gives us a clue as to why you can distinguish an array from one reference type to a subtype - its because it is just a bit discarded from one type of pointer to another. This will work for super / subtype classes, but not for arbitrary classes, structures, or protocols, since they have different binary representations.
source share