《Swift进阶》ReadingNotes_7

泛型的使用:

1:使用泛型约束进行重载
extension Sequence where Iterator.Element: Equatable{
    func isSubset(of other: [Iterator.Element])->Bool{
        for element in self {
            guard other.contains(element) else {
                return false
            }
        }
        return true
    }
}

let one_three = [1,2,3]
let one_five = [1,2,3,4,5]
let a = one_three.isSubset(of: one_five)
print(a)//true

这上面的用法中,我们并不关心这个序列的元素具体是什么类型,只是要求元素可以判等即可,所以给定一个 Equatable泛型约束。

2.使用闭包对行为进行参数化:
extension Sequence{
    func isSubSet(of other: S,euqalEvent:@escaping (Iterator.Element,S.Iterator.Element)->Bool)->Bool{
        for element in self{
            guard other.contains(where:{return euqalEvent(element,$0)}) else {
                return false
            }
        }
        return true
    }
}
print([[1,2]].isSubSet(of: [[1,2],[3,4]]){ $0 == $1 })

3.创建泛型数据类型,提取代码共通性

泛型的工作方式:

对于每个泛型类型的参数,编译器维护了一系列一个或者多个目击表(witness table)其中包含一个值目击表,以及类型上每个协议约束的一个协议目击表。这些目击表(也称vtable)将被用来将运行时的函数动态派发到正确的实现去。
  对于任意的泛型类型,总会存在目击表,它包含了指向内存申请,复制和释放这些类型的基本操作指针。这些操作对于像Int这样的类型来说,可能不需要额外的操作,或者只是简单的内存复制,不过对于引用类型来说,这里也会包含引用计数的逻辑。目击表同时还记录了类型的大小和对齐方式。
  协议目击表提供了一组映射关系,通过这组映射,我们可以知道泛型类型满足的协议 (编译器通过泛型约束可以静态地知道这个信息) 和某个具体类型对于协议功能的具体实现 (这只在运行时才能知道) 的对应关系。实际上,只有通过目击表我们才能查询或者操作某个值

泛型优化--泛型特化:

泛型特化是指,编译器按照具体的参数参数类型 (比如 Int),将 min 这样的泛型类型或者函数进行复制。特化后的函数可以将针对 Int 进行优化,移除所有的额外开销。这不仅能去掉派发的开销,还可以让像是内联等进一步优化成为可能。由于原来的函数是被非直接使用的,这些优化以前是无法实行的

你可能感兴趣的:(《Swift进阶》ReadingNotes_7)