美文网首页iOS基础知识
第一篇:IteratorProtocol

第一篇:IteratorProtocol

作者: NinthDay | 来源:发表于2017-02-26 19:38 被阅读379次

    迭代器(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

    相关文章

      网友评论

      本文标题:第一篇:IteratorProtocol

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