迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。迭代器修改了常规指针的接口,所谓迭代器是一种概念上的抽象:那些行为上像迭代器的东西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把抽象容器和通用算法有机的统一起来。
Generator已经被IteratorProtocol取代,但仅仅是名字的修改而已,现定义如下:
public protocol IteratorProtocol {
associatedtype Element
public mutating func next() -> Self.Element?
}
head first 设计模式中有一章是迭代器模式
class DishesIterator:IteratorProtocol {
var dishes:[String]
var idx = -1
typealias Element = String
init(dishes:[String]) {
self.dishes = dishes
self.idx = -1
}
func next() -> String? {
idx = idx + 1
if idx < dishes.count {
return dishes[idx]
} else {
return nil
}
}
}
let dIterator = DishesIterator(dishes: ["🐟","🦐"])
dIterator.next()
dIterator.next()
dIterator.next()
这么写有点挫,利用 swift 提供的removeFirst 方法改写
class DishesIterator:IteratorProtocol {
var dishes:[String]
typealias Element = String
init(dishes:[String]) {
self.dishes = dishes
}
func next() -> String? {
return dishes.removeFirst()
}
}
let dIterator = DishesIterator(dishes: ["🐟","🦐"])
dIterator.next()
使用泛型更为通用:
class MyIndexingIterator<T>:IteratorProtocol {
var content:[T]
init(content:[T]) {
self.content = content
}
func next() -> T? {
return content.removeFirst()
}
}
let dIterator = MyIndexingIterator(content: ["🐟","🦐"])
dIterator.next()
let iIterator = MyIndexingIterator(content: [1,2])
iIterator.next()
let fIterator = MyIndexingIterator(content: [1.1,2.1])
fIterator.next()
泛型的推断时机是在初始化声明之处,[T] 和传入的元素数组类型绑定,接着又和 next()->T?
中的 T 绑定。
实战
读取文件内容的迭代器
class FileLinesIterator: IteratorProtocol {
typealias Element = String
var lines: [String] = []
// 这里你可以用传入filename 来读取content try String(contentsOfFile: lename) 即可
init (content: String) {
let contents = content
let newLine = CharacterSet.newlines
lines = contents.components(separatedBy: newLine)
}
func next() -> Element? {
guard !lines.isEmpty else{return nil }
let nextLine = lines.removeFirst()
return nextLine
}
}
// 模拟从文件中读取的内容 有换行的
var content = "xsdsdsdsdsdssdsdsdqqqq\nwe你好我得到的\ns设定设定所多"
var iterator = FileLinesIterator(content: content)
iterator.next()
我将定期更新有关此分类的学习笔记。
请关注我的微博:Ninth_Day