2017-04-05 83 views
2

據我所知,身份運算符用於確定兩個對象是否具有相同的引用。這意味着,在實踐中,操作員的雙方應該是一個對象。身份運算符還可以檢查命名類型是否相同,而不僅僅是參考相同

不過,我已經試過下面的代碼,它讓我感到困惑的是什麼我明白

class Dog {} 

let d: Dog = Dog() 

if type(of: d) === Dog.self { 
    print("yep") //prints out "yep" 
} 

if type(of: d) == Dog.self { 
    print("yep") //prints out "yep" 
} 

身份運算符的左側和右側的身份運營商的功能是不是對象,但類型和看來,對於這一點,語義等價運算符和對象身份運算符(看起來像)以相同的方式工作。

問題

這是一個錯誤或我沒有得到正確的整點。

感謝您的幫助和時間

回答

1

身份運算符的左側和右側不是對象而是類型。

其實,在蘋果平臺上,他們都是對象。

這是由於Swift類在底層實現爲Objective-C類,因爲Mike Ash詳細描述了in this great blog post。這意味着一個類的元類型是也是一個Objective-C類,因此符合01​​。

正因爲如此,你可以用身份操作比較類元類型,因爲它的定義爲:

public func ===(lhs: AnyObject?, rhs: AnyObject?) -> Bool 

它會比較兩個對象是否是同一個對象,或者特別是在這種情況下,相同的類metatype。

相比之下,值類型的元類型不是Objective-C對象 - 它只是指向某些靜態元數據的指針。如果我們重寫你的榜樣使用struct

struct Dog {} 

let d = Dog() 

// Binary operator '===' cannot be applied to two 'Dog.Type' operands 
if type(of: d) === Dog.self { 
    print("yep") 
} 

你會看到,我們可以不再使用===比較元類型,因爲它們不符合AnyObject。實際上,使用身份運算符來比較類元類型的能力只是它們作爲Objective-C對象實現的副作用。

比較元類型的普遍方法是用等號運算符==,如雨燕專門爲元類型提供了一個過載:

public func ==(t0: Any.Type?, t1: Any.Type?) -> Bool 

此檢查兩個元類型是否是一樣的,但是,不像===,它的工作原理與均爲類元類型和值類型的元類型。在引擎蓋下,它執行as a simple pointer comparison,所以應該總是產生與===一樣的結果,並帶有元類型。

因此,我總是建議您將元數據類型與==進行比較,因爲您並不依賴與AnyObject的一致性。例如,在Linux平臺上,class metatypes don't conform to AnyObject因此不能與身份運算符進行比較(儘管有趣的是,當導入Foundation時,似乎爲AnyObject.Type操作數增加了===重載 - 可能有助於互操作性)。

1

不是一個錯誤,它們是相同的東西。

狗,作爲一個類(類型)是一個單數,只能有一個。可以有許多實例,但只有一個類。

type(of:d)返回所有者d的類,Dog.self返回類本身。他們是完全相同的對象,單數類的狗。

+0

感謝您的善意幫助:) – SLN

相關問題