美文网首页
Swift类型系统 protocol中的Self

Swift类型系统 protocol中的Self

作者: Zafir_zzf | 来源:发表于2021-10-13 11:37 被阅读0次

背景

Swift的类型系统意在帮助开发者在编译期间构建 稳定健壮的代码。但类型系统有时会给我们带来一些阻碍,当然也正是因为这些"阻碍",才有了稳定。

协议中的关联类型

下面是一个比较经典的情况

image.png
Collection协议因为定义了associatedtype ,无法直接作为参数或者返回值
protocol Collection : Sequence {
    associatedtype Element
}

至于为什么有associatedtype Element就无法作为参数或者返回值,作为编译检查严格的Swift这里还是可以理解的,因为当我们使用这个关联类型的协议的时候,Element具体类型是什么编译器无法得知,在调用对应方法时候也就没有了检查(无法确定类型),这是不被允许的。例如:

func test(c: Collection) {
     c.first? //   编译器该怎么定义这个类型是什么呢?
}

Collection作为函数返回值同理

func test() -> Collection {
        
}
test().first? // 这到底是个什么类型

协议中的Self

Self作为参数 不可行

除了协议中的关联类型associatedtype,还有一种情况也会让协议无法作为参数和返回值

func test(l: Equatable, r: Equatable) -> Bool {
  return l == r
}

Equatable的定义中有Self相关的函数

protocol Equatable {
    static func == (lhs: Self, rhs: Self) -> Bool
}

这个也是比较容易理解的。虽然test函数中的l r都是Equatable,但是==要求判断的是同一种具体类型,而这里的test函数可以传入任何两种类型

Self作为返回值 可行

但如果是这种协议,它是能作为函数的返回值的

protocol Copyable {
    func copy() -> Self
}

带有associatedtype的协议,不管这个type作为协议中的函数还是返回值都无法直接在其他函数中使用
带有Self的协议,如果Self用作参数,无法在其他函数中直接使用,如果Self作为返回值,可以在其他函数中直接使用

那么将Self作为参数和返回值为啥会有区别呢?

联系前面编译检查严格的例子,这种协议在作为参数的时候,可能会直接调用到关于Self的函数而让编译器不知所措,而作为返回值,我们无法直接使用到关于Self这个类型的地方,而是相当于返回了一个具体的协议,编译器并不会觉得模棱两可

相关文章

网友评论

      本文标题:Swift类型系统 protocol中的Self

      本文链接:https://www.haomeiwen.com/subject/scjloltx.html