Although each type corresponds to Any
, it is not the same as being a universal implicit superclass to which all types inherit.
When you apply a type to a protocol, you create a new value with a different structure. Therefore, for a string of type Any
it must be physically converted from the String
view:
sizeof(String)
to Any
view:
sizeof(Any)
Since the types of values ββare stored directly in the array, the array will have a completely different shape, so under the hood the compiler will have to do the equivalent of this:
names.map { $0 as Any }
Swift could automate this process for you (this happens if you pass one variable to a function that accepts Any
). But Im personally glad that this is not so, I'd rather be more explicit - suppose your array was huge, that would be a lot of processing happening implicitly under the hood.
This is different than when you have an array of reference types, all of which are pointers to the actual data and therefore are the same size and do not need to be converted when raising:
class C { } class D: C { } let d = D() let c: C = d unsafeBitCast(d, UnsafePointer<Void>.self)
Thus, βthis array [D]
is really an array from [C]
β is just a compiler question, agreeing that types can be replaced, data conversion should not occur:
// so this works fine, // no runtime transformation needed: func f(cs: [C]) { } let ds = [D(),D()] f(ds)
But the protocols are still different from references to superclasses when used with classes:
protocol P { } extension C: P { } sizeofValue(C())