• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Swiftself,Self,==,===傻傻分不清楚?

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

 

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

 

内容概览

  • 前言

  • selfSelf

  • =====

  • 总结

 

前言

 

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

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

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

 

selfSelf

 

实例中的 self

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

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

 

类型中的 self

如上图所示,Xcode 会告诉你这个 selfTestClass.Type 类型。稍等一下,.Type 是什么东西?
从字面意思去理解,这个 selfTestClass 这个类型本身。

如果为该类型定义一个静态常量(static let),我们就可以在类型的静态方法(static func)中去访问这个静态常量。因为,它们都属于这个类型本身。self.classLet 也就是在访问 TestClass 这个类型本身的常量 classLet

 

实体类型(concrete type)中的 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 是未定义的。
如果使用懒加载的属性,要注意区分 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 。在掌握新特性的同时,不定期地去温习旧的基础知识,这样可以有效地保证自己的认知没有与现实脱节~

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

 
 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Swift-技巧(七)重识 Array发布时间:2022-07-13
下一篇:
Swift开发小技巧--自定义转场动画发布时间:2022-07-13
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap