本文首发于 Ficow Shen's Blog,原文地址: Swift self, Self, ==, === 傻傻分不清楚?。html
前言面试
self
和 Self
swift
==
和 ===
ide
总结函数
在2014年开源以后,Swift就在飞速地茁壮成长,内涵也愈来愈丰富。post
对于实际使用Swift的人来讲,概念多了就比较容易混淆😨,而后就会致使开发效率低下。毕竟,你须要去查这些概念的正肯定义,或者你须要去写代码进行验证。self, Self, ==, === 就是比较典型的例子。ui
在面试别人的过程当中,我发现有不少朋友分不清楚这些概念。因此,我打算根据我本身的理解来梳理一下这些概念,但愿可以帮你们少走一些弯路。🌟🌟🌟指针
self
和 Self
self
首先,最简单的确定是实例中的 self
了:code
如上图所示,Xcode 会告诉你这个 self
属于 TestClass
类型。htm
self
:如上图所示,Xcode 会告诉你这个 self
是 TestClass.Type
类型。稍等一下,.Type
是什么东西?
从字面意思去理解,这个 self
是 TestClass
这个类型自己。
若是为该类型定义一个静态常量(static let
),咱们就能够在类型的静态方法(static func
)中去访问这个静态常量。由于,它们都属于这个类型自己。self.classLet
也就是在访问 TestClass
这个类型自己的常量 classLet
。
Self
请看,咱们能够直接经过 Self
去访问类型上的属性:
可是,这个 Self
不等于 self
。
上图中的 print
函数会打印 true
。为何呢?
请推测一下,print(TestClass.self == self)
会打印 true
仍是 false
?
请不要中止思考,更有意思的来了😹:
请问,这些 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
是未定义的。
若是使用懒加载的属性,要注意区分 self
和 Self
。由于实例已经完成了初始化,此时 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
。在掌握新特性的同时,不按期地去温习旧的基础知识,这样能够有效地保证本身的认知没有与现实脱节~
以上就是本文的所有内容,若有谬误,麻烦帮我指出。 若是你也有推荐阅读的内容,请留言告诉我,你们共同进步!谢谢~ 🤗