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

 

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

 

内容概览

  • 前言

  • selfSelf

  • =====

  • 总结

 

前言

 

在2014年开源之后,Swift就在飞速地茁壮成长,内涵也越来越丰富。

对于实际使用Swift的人来说,概念多了就比较容易混淆😨,然后就会导致开发效率低下。毕竟,你需要去查这些概念的正确定义,或者你需要去写代码进行验证。self, Self, ==, === 就是比较典型的例子。

在面试别人的过程中,我发现有很多朋友分不清楚这些概念。所以,我打算根据我自己的理解来梳理一下这些概念,希望能够帮大家少走一些弯路。🌟🌟🌟

 

selfSelf

 

实例中的 self

首先,最简单的肯定是实例中的 self 了:

图片alt

如上图所示,Xcode 会告诉你这个 self 属于 TestClass 类型。

 

类型中的 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 。在掌握新特性的同时,不定期地去温习旧的基础知识,这样可以有效地保证自己的认知没有与现实脱节~

以上就是本文的全部内容,如有谬误,麻烦帮我指出。
如果你也有推荐阅读的内容,请留言告诉我,大家共同进步!谢谢~ 🤗

 
 

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345