[Swift]自定义队列Queue索引超界

本身这个问题并不难,主要是支持enqueue和dequeue方法。网上有很多例子,这里不赘述。
为了支持for in 循环,一般还会实现Sequence协议。

网上个别例子可能在swift 4就会有错误。
因为同时实现了Collection之类的协议,导致隐藏了对Sequence实现的问题。

当for in 的集合元素为0个时会发生索引超界异常。

是makeIterator,不是generate

如果是在一个纯净的环境实现了Sequence ,写成generate马上就编译报错了,但是如果同时跟Collection之类的协议有关系,因为Collection继承自Sequence,会导致问题被隐藏起来了。

 //扩展队列的for...in循环功能
extension Cat008_Queue: Sequence {

    // 从序列中返回一个迭代器
    //public func generate() -> AnyIterator { //这个方法无效并不存在于 Sequence
    public func makeIterator() -> AnyIterator  {
        return AnyIterator(IndexingIterator(_elements: data.lazy))
    }
}

队列实现的简单基本功能代码


// 定义一个队列结构
public struct Cat008_Queue {

    // 数组用来存储数据元素
    private var data = [T]()
    
    // 构造方法,用于构建一个空的队列
    public init() {}
    
    
    // 将类型为T的数据元素添加到队列的末尾
    public mutating func enqueue(element: T) {
        data.append(element)
    }
    
    // 移除并返回队列中第一个元素
    // 如果队列不为空,则返回队列中第一个类型为T的元素;否则,返回nil。
    public mutating func dequeue() -> T? {
        return data.removeFirst()
    }
    
    // 清空队列中的数据元素
    public mutating func clear() {
        data.removeAll()
    }
}

 //扩展队列的for...in循环功能
extension Cat008_Queue: Sequence {

    // 从序列中返回一个迭代器
    //public func generate() -> AnyIterator { //这个方法无效并不存在于 Sequence
    public func makeIterator() -> AnyIterator  {
        return AnyIterator(IndexingIterator(_elements: data.lazy))
    }
}

测试方法

func runTest() {
        
        var k = Cat008_Queue()
        k.enqueue(element: 2)
        k.enqueue(element: 5)
        for item in k {
            print(item)
        }
        
        //在受到extension了其他collcetion类干扰的情况下,
        //对Sequence的扩展中写的方法名是generate(),则在
        //for循环的集合元素个数=0时会崩溃,下标超界
        var mm = Cat008_Queue()
        for item in mm {
            print(item)
        }
        
        print("end \(type(of:self)) test")
    }

你可能感兴趣的:([Swift]自定义队列Queue索引超界)