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]))
所以当我运行时,我得到:
D
D
Array<P1>
好的,所以我来自C ++世界。我想第一行会给我一种P1,第二行会给我一种B类型,第三行会给我一个P1数组。所以我得到P1的数组,但这似乎与第一行不一致,这表明它真的是D而不是P1。什么给出了什么?显然,我不理解斯威夫特的这个角落。当你向上倾斜时,它不应该忽略这种类型的信息吗?编译器是否太聪明,因为它真的知道类型?
答案 0 :(得分:1)
编译器是否太聪明,因为它确实知道类型?
编译器只知道你告诉它的内容。它认为D() as B
是B。
但是你没有问过编译器。当您说print
并运行应用程序时,您正在与运行时进行通信。多态性表示对象是它实际上是内部的类型,而不是其他类型。您可以将D()
转换为P1或B,但它仍然是D.您运行应用程序,运行时会发现它,它会告诉您它发现了什么。
阵列情况略有不同。在Swift中,Array是通用的,必须解决。您对如何解决它的陈述是决定性的,即使对于运行时:
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>
*/
换句话说,运行时并不打算探索这些数组,并告诉你它们的最低公分母;它只是告诉你类型。但是如果你自己探索阵列,你会发现它们中的内容:
for element in ([D(), D()] as [P1]) { print(type(of:element)) }
// D D
答案 1 :(得分:0)
type(of: ...)
返回值的动态类型,而不是静态类型。它相当于在C ++中使用RTTI。
https://developer.apple.com/documentation/swift/2885064-type