前言
self 和 Self
== 和 ===
总结
在2014年开源之后,Swift就在飞速地茁壮成长,内涵也越来越丰富。
对于实际使用Swift的人来说,概念多了就比较容易混淆😨,然后就会导致开发效率低下。毕竟,你需要去查这些概念的正确定义,或者你需要去写代码进行验证。self, Self, ==, === 就是比较典型的例子。
在面试别人的过程中,我发现有很多朋友分不清楚这些概念。所以,我打算根据我自己的理解来梳理一下这些概念,希望能够帮大家少走一些弯路。🌟🌟🌟
self 和 Self
self首先,最简单的肯定是实例中的 self 了:

如上图所示,Xcode 会告诉你这个 self 属于 TestClass 类型。
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 。在掌握新特性的同时,不定期地去温习旧的基础知识,这样可以有效地保证自己的认知没有与现实脱节~
以上就是本文的全部内容,如有谬误,麻烦帮我指出。
如果你也有推荐阅读的内容,请留言告诉我,大家共同进步!谢谢~ 🤗
觉得不错?点个赞呗~
本文链接:Swift self, Self, ==, === 傻傻分不清楚?
转载声明:本站文章如无特别说明,皆为原创。转载请注明:Ficow Shen's Blog