Swift详解之一 -------- 变量声明

时间:2021-07-01 16:50:39   收藏:0   阅读:0

内容概览

 

前言

 

在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

 

实体类型(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 是未定义的。
如果使用懒加载的属性,要注意区分 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 是最终实现协议的那个类型。

 

== 和 ===

 

==

示例

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
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!