2017-10-06 19 views
2
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])) 

所以,当我跑,我得到:用“as”快速上传,发生了什么?

D 
D 
Array<P1> 

好了,我可是从C++的世界即将到来。我想第一行会给我一个P1类型,第二行会给我一个B类型,第三行会给我一个P1数组。所以我得到了P1的数组,但是与第一行似乎不一致,它指出它的确是D而不是P1。那么是什么给了?显然,我不明白Swift的这个角落。当你上传时,不应该忽视这种类型的信息吗?编译器是否太聪明,因为它真的知道类型?

回答

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 
+0

好的,谢谢马特(和Ewan)。是的,第三种情况(数组)是什么让我失望,所以感谢编辑清除了。 – DavidN