美文网首页
Swift 集合类新协议 Collection

Swift 集合类新协议 Collection

作者: 你duck不必呀 | 来源:发表于2021-11-11 16:55 被阅读0次

    集合类型

    集合类型 (Collection) 指的是那些稳定的序列,它们能够被多次遍历且保持一致。除了线性遍历以外,集合中的元素也可以通过下标索引的方式被获取到,因此集合类型不能是无限的

    Collection协议

    Swift中Collection协议是建立在Sequence协议之上的,为有限的序列提供下标访问的能力,同时增加了count属性,自定义索引等特性

    想要遵守Collection协议,除了实现Sequence要求的方法,还包括下标索引相关的方法。而swift中的下标索引除了可见的下标(整数)还有不可见下标索引(哈希),所以必须选取一个合适的索引来表达集合中元素的位置,好在系统提供了默认实现。实际满足Collection协议的最小要求如下:

    struct customCollection<T>:Collection{
        var buffer:[T]
        typealias Index = Int
        // startIndex 和 endIndex
        var startIndex: Index{ get }
        var endIndex: Index{ get }
    
        //集合索引之间 步进 
        func index(after i: Index) -> Index
        //至少能够读取你的类型中的元素下标方法
        subscript(position: Index) -> T { get }
        }
    

    关联类型

    associatedtype Iterator = IndexingIterator<Self>
    

    IndexingIterator迭代器

    这是从Sequence继承来的,IndexingIterator是集合的迭代器, 实现了IteratorProtocol要求的next()方法,用集合自身的索引迭代每个元素

    struct IndexingIterator<Elements: Collection> {
      //...
      //IteratorProtocol 协议要求的next()
        public mutating func next() -> Elements.Element? {
        if _position == _elements.endIndex { return nil }
        let element = _elements[_position]
        _elements.formIndex(after: &_position)
        return element
      }
      //...
    }
    

    SubSequence

    associatedtype SubSequence: Collection = Slice<Self>
      where SubSequence.Index == Index,
            Element == SubSequence.Element,
            SubSequence.SubSequence == SubSequence
    

    集合都能够进行切片操作,返回SubSequence子类型,SubSequence本身也是一个Collection,是从Sequence协议继承来的,类型Slice<Self>是对原来集合的分装,集合类型和它的切片拥有相同的索引

    Indices

      associatedtype Indices: Collection = DefaultIndices<Self>
        where Indices.Element == Index, 
              Indices.Index == Index,
              Indices.SubSequence == Indices
    
    

    它是集合中所有有效索引按升序排列组成的集合,不包含endIndex

    index

    associatedtype Index: Comparable
    

    Collection协议对Index的要求是遵守Comparable协议,每个集合都有两个特殊的索引值:startIndex 和 endIndex。startIndex 指定集合中第一个元素,endIndex 是集合中最后一个元素的下一个位置,内置类型Array的索引类型是Int类型,String的索引类型是StringIndex,字典Dictionary的索引类型是DictionaryIndex

    index(after:)

    func index(after i: Index) -> Index
    

    从一个给定索引计算出下一个元素的索引

    自定义集合遵守Collection协议

    struct customCollection<T>:Collection{
        var buffer:[T]
       //简单的数组类型,索引类新定义为Int即可
        typealias Index = Int
        var startIndex: Int {
            return 0
        }
        var endIndex: Int {
            return buffer.count
        }
        func index(after i: Int) -> Int {
            return I+1
        }
        subscript(position: Int) -> T {
            return buffer[position]
        }
    }
    var collection = customCollection(buffer: [1,2,3,4,5,6,7,8,9,10])
    // 可通过下标访问
    collection[5]// 6
    //可以遍历
    for i in collection{
        print(i)
    }
    

    通过遵守Collection协议,自定义类型customCollection拥有来自Sequence和Collection协议中的全部属性和方法

    特定的集合类型协议

    Collection协议的基本要求是为有限的序列提供下标访问能力,但是大多数集合还包括修改,移除元素,替换等操作。当然,这并不是说满足 Collection 的类型不能拥有这些能力,只是 Collection 协议自身没有把它们当作必须要实现的功能。

    有些算法会对集合支持的操作有额外的要求,这使得只有部分集合可以和它们搭配在一起工作。如果可以把这些额外的要求抽象出来形成一些通用的集合变体,用起来就会更加方便。为此,标准库提供了四个专门的集合类型,每一个都用特定的方式给 Collection 追加了新的功能

    支持双向索引的集合BidirectionalCollection

    随机存取集合类型RandomAccessCollection

    可变集合协议,支持原地修改元素MutableCollection

    添加,移除操作的元素的集合RangeReplaceableCollection


    最后附上一张Swift集合协议大家族构成图:

    image.png

    相关文章

      网友评论

          本文标题:Swift 集合类新协议 Collection

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