Reputation: 8237
protocol P1 {
func doP1()
}
protocol P2 {
func doP2()
}
class B {
}
class D : B, P1, P2 {
func doP2() {}
func doP1() {}
}
let s = D()
print(type(of:(D() as P1)))
print(type(of:(D() as B)))
print(type(of:[D(), D()] as [P1]))
So when I run this, i get:
D
D
Array<P1>
ok, so Im coming from the C++ world. I figured the first line would give me a type of P1, the second would give me a type of B, and the third would give me an array of P1. So I get the array of P1, but that seems inconsistant with the first line, which figures out that its really a D and not a P1. So what gives? Clearly,I don't understand this corner of Swift. When you upcast, shouldn't it disregard this type info? Is the compiler too smart, because it really knows the types?
Upvotes: 2
Views: 576
Reputation: 536009
Is the compiler too smart, because it really knows the types?
The compiler knows only what you tell it. It thinks D() as B
is a B.
But you didn't ask the compiler. When you say print
and run the app, you're talking to the runtime. Polymorphism says that an object is the type it actually is, internally, and not some other type. You can cast D()
to P1 or B but it is still a D. You run the app, the runtime discovers this, and it tells you what it discovered.
The Array situation is slightly different. In Swift, Array is a generic, and must be resolved. Your statement of how it should be resolved is decisive, even for the runtime:
print(type(of:[D(), D()] as [P1]))
print(type(of:[D(), D()] as [P2]))
print(type(of:[D(), D()] as [B]))
/*
Array<P1>
Array<P2>
Array<B>
*/
In other words, the runtime doesn't bother to explore these arrays and tell you their lowest common denominator, as it were; it just tells you the type. But if you were to explore the arrays yourself, you'd find out what is in them:
for element in ([D(), D()] as [P1]) { print(type(of:element)) }
// D D
Upvotes: 2
Reputation: 6857
type(of: ...)
in Swift returns the dynamic type of the value, not its static type. It's the equivalent of using RTTI in C++.
https://developer.apple.com/documentation/swift/2885064-type
Upvotes: 0