2017-10-06 20 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