Swift self, Self, ==, === 傻傻分不清楚?

 

本文首發於 Ficow Shen's Blog,原文地址: Swift self, Self, ==, === 傻傻分不清楚?html

 

內容概覽

  • 前言面試

  • selfSelfswift

  • =====ide

  • 總結函數

 

前言

 

在2014年開源以後,Swift就在飛速地茁壯成長,內涵也愈來愈豐富。post

對於實際使用Swift的人來講,概念多了就比較容易混淆😨,而後就會致使開發效率低下。畢竟,你須要去查這些概念的正肯定義,或者你須要去寫代碼進行驗證。self, Self, ==, === 就是比較典型的例子。ui

在面試別人的過程當中,我發現有不少朋友分不清楚這些概念。因此,我打算根據我本身的理解來梳理一下這些概念,但願可以幫你們少走一些彎路。🌟🌟🌟指針

 

selfSelf

 

實例中的 self

首先,最簡單的確定是實例中的 self 了:code

圖片alt

如上圖所示,Xcode 會告訴你這個 self 屬於 TestClass 類型。htm

 

類型中的 self

圖片alt

如上圖所示,Xcode 會告訴你這個 selfTestClass.Type 類型。稍等一下,.Type 是什麼東西?
從字面意思去理解,這個 selfTestClass 這個類型自己。

圖片alt

若是爲該類型定義一個靜態常量(static let),咱們就能夠在類型的靜態方法(static func)中去訪問這個靜態常量。由於,它們都屬於這個類型自己。self.classLet 也就是在訪問 TestClass 這個類型自己的常量 classLet

 

實體類型(concrete type)中的 Self

請看,咱們能夠直接經過 Self 去訪問類型上的屬性:

圖片alt

可是,這個 Self 不等於 self

圖片alt

上圖中的 print 函數會打印 true。爲何呢?

圖片alt

請推測一下,print(TestClass.self == self) 會打印 true 仍是 false

請不要中止思考,更有意思的來了😹:
圖片alt

請問,這些 print 會分別打印什麼內容?

 
 

好吧,結果是 3 行 true。因此, 這個 Self 等同於當前這個實體類型,對嗎?

抱歉,不對!!!🤭 根據 官方文檔 的內容,這個 Self 的值等於 type(of: self)。也就是說,這個值是動態獲取的!

 

如今,讓咱們來看一個示例:

class TestClass {
    static let classLet = 0
    
    let instanceLet = classLet // 不能寫成 self.classLet
    var instanceVar = classLet
    
    lazy var instanceLazyVar = Self.classLet // 不能寫成 self.classLet
}

若是須要用類型中的屬性來初始化實例中的屬性,就能夠參考上面這種方法。注意,不能寫成 let instanceLet = self.classLet。這樣寫會出現編譯錯誤,self 是未定義的。
若是使用懶加載的屬性,要注意區分 selfSelf。由於實例已經完成了初始化,此時 self 是有效的。

 

若是將 Self 用在協議中,好比:

protocol TestProtocol {
    func getSelf() -> Self
}
class TestBaseClass: TestProtocol {
    func getSelf() -> Self {
        return self
    }
}
class TestSubclass: TestBaseClass {
    override func getSelf() -> Self {
        return self
    }
}
let base: TestBaseClass = TestBaseClass()
let sub: TestSubclass = TestSubclass()

此時,Self 是最終實現協議的那個類型。

 

=====

 

==
  • Equatable 協議中定義的方法:static func == (lhs: Self, rhs: Self) -> Bool
  • 否認形式:!=
  • 支持自定義比較,規則能夠由開發者自行定義比較的規則;

示例

class MyType: Equatable {
    let id: UUID
    let name: String

    init(id: UUID, name: String) {
        self.id = id
        self.name = name
    }

    static func == (lhs: MyType, rhs: MyType) -> Bool {
		// lhs: left-hand side, rhs: right-hand side
		
        // 也能夠是: return lhs.id == rhs.id,規則由你來定義
        return lhs.id == rhs.id && lhs.name == rhs.name
    }
}

// 還能夠這樣定義:
class MyType: Equatable {
    let name: String

    init(name: String) {
        self.name = name
    }

    static func == (lhs: MyType, rhs: MyType) -> Bool {
		// ObjectIdentifier 不支持值類型
		// 也能夠這樣比較: return lhs === rhs
        return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
    }
}

 

===
  • 比較的是指針,因此只能用於比較引用類型;
  • 否認形式:!==
  • 不支持開發者自定義比較的規則;

示例

NSObject() === NSObject()

 

相關文檔
Equivalence Operators(==)
Identity Operators(===)

 

總結

 

這些是比較經常使用並且比較基礎的語法知識點,咱們要爭取理解到位,不然就會影響到開發效率。

這是 Swift 的 Revision History(文檔修訂歷史),建議你們多關注。好比 SwiftUI 中最多見的 some 關鍵字就是在 Swift 5.1 中新增的 Opaque Types 。在掌握新特性的同時,不按期地去溫習舊的基礎知識,這樣能夠有效地保證本身的認知沒有與現實脫節~

以上就是本文的所有內容,若有謬誤,麻煩幫我指出。 若是你也有推薦閱讀的內容,請留言告訴我,你們共同進步!謝謝~ 🤗

相關文章
相關標籤/搜索