override func makeIterator() -> IteratorImpl {
return IteratorImpl(seq.makeIterator())
}
}
我们需要一种方法来实际创建这些东西:对 MAnySequence 添加一个静态方法,该方法创建一个 MAnySequenceImpl 实例,并将其作为 MAnySequence 类型返回给调用者。
extension MAnySequence {
static func make<Seq: Sequence>(_ seq: Seq) -> MAnySequence<Element> where Seq.Element == Element {
return MAnySequenceImpl<Seq>(seq)
}
}
在实际开发中,我们可能会做一些额外的操作来让 MAnySequence 提供一个初始化方法。
我们来试试 MAnySequence:
func printInts(_ seq: MAnySequence<Int>) {
for elt in seq {
print(elt)
}
}
let array = [1, 2, 3, 4, 5]
printInts(MAnySequence.make(array))
printInts(MAnySequence.make(array[1 ..< 4]))
完美!
基于函数的类型擦除
有时我们希望对外暴露支持多种类型的方法,但又不想指定具体的类型。一个简单的办法就是,存储那些签名仅涉及到我们想公开的类型的函数,函数主体在底层已知具体实现类型的上下文中创建。
我们一起看看如何运用这种方法来设计 MAnySequence,与前面的实现很类似。它是一个结构体而非类,这是因为它仅仅作为容器使用,不需要有任何的继承关系。
struct MAnySequence<Element>: Sequence {
跟之前一样,MAnySequence 也需要一个可返回的迭代器(Iterator)。迭代器同样被设计为结构体,并持有一个参数为空并返回 Element? 的存储型属性,实际上这个属性是一个函数,被用于 IteratorProtocol 协议的 next 方法中。接下来 Iterator 遵循 IteratorProtocol 协议,并在 next 方法中调用函数:








