Swift团队于上周开源新软件包SwiftCollections,以扩展Swift的数据结构集合。这个新的开源软件包与SwiftAlgorithms和SwiftNumerics一样,目的在于扩展Swift标准库的新功能。Swift标准库目前实现了三个最基本的通用数据结构:Array、Set和Dictionary,这几个数据结构可以满足基本的需求,但有时候为了更有效地解决问题或保持不变性,开发人员可能需要更多的数据结构。而SwiftCollections软件包就提供了不少新的数据结构,以让开发人员可以以更少的精力编写更快、更可靠的程序。
我们这里简要介绍一下SwiftCollections里新的数据结构。
Collections包的初始版本包含三个最常用的数据结构的实现:双端队列,有序集合和有序字典。
DequeDeque的工作方式与Array十分相似:它是一个有序、可随机访问、可变、范围可替换且具有整数索引的集合。Deque优于Array的主要好处是它支持两端的有效插入和删除。如果需要FIFO队列时,双端队列都是一个不错的选择。
varcolors:Deque=["red","yellow","blue"]colors.prepend("green")colors.append("orange")//`colors`isnow["green","red","yellow","blue","orange"]colors.popFirst()//"green"colors.popLast()//"orange"//`colors`isbackto["red","yellow","blue"]
也可以使用任何熟悉的MutableCollection和RangeReplaceableCollection方法来访问和修改集合的元素。索引的工作方式与数组中完全相同–第一个元素始终位于索引零处:
colors[1]//"yellow"colors[1]="peach"colors.insert(contentsOf:["violet","pink"],at:1)//`colors`isnow["red","violet","pink","peach","blue"]colors.remove(at:2)//"pink"//`colors`isnow["red","violet","peach","blue"]colors.sort()//`colors`isnow["blue","peach","red","violet"]
为了支持在前面的有效插入,双端队列需要放弃将其元素保持在连续的缓冲区中。对于不需要在前端插入/删除元素的情况,这往往会使它们的工作速度比数组慢一些,因此用双端队列盲目替换所有数组可能不是一个好主意。
OrderedSetOrderedSet是数组和集合的强大混合体。我们可以使用任何符合Hashable协议的元素类型创建有序集合:
letbuildingMaterials:OrderedSet=["straw","sticks","bricks"]
像Array一样,有序集合按用户指定的顺序维护其元素,并支持对其成员的有效随机访问遍历:
foriin0..buildingMaterials.count{print("Littlepiggie#\(i)builtahouseof\(buildingMaterials)")}//Littlepiggie#0builtahouseofstraw//Littlepiggie#1builtahouseofsticks//Littlepiggie#2builtahouseofbricks
像Set一样,有序集合可确保每个元素仅出现一次并提供有效的成员测试:
buildingMaterials.append("straw")//(inserted:false,index:0)buildingMaterials.contains("glass")//falsebuildingMaterials.append("glass")//(inserted:true,index:3)//`buildingMaterials`isnow["straw","sticks","bricks","glass"]
OrderedSet用标准数组来存储元素,可以以最小的开销提取元素。如果我们要将有序集合的内容传递给仅接受数组的函数(或在RangeReplaceableCollection或MutableCollection上通用)的函数,则可以用以下方式:
funcbuildHouses(_houses:ArrayString)buildHouses(buildingMaterials)//errorbuildHouses(buildingMaterials.elements)//OKOrderedDictionary
当元素的顺序很重要或我们需要能够有效访问集合中各个位置的元素时,OrderedDictionary是Dictionary的有用替代方法。我们可以使用符合Hashable协议的任何键类型创建有序字典:
letresponses:OrderedDictionary=[:"OK",:"Forbidden",:"NotFound",]
OrderedDictionary提供了许多与Dictionary相同的操作。例如,我们可以使用下标有效地查找并添加值:
responses[]//"OK"responses[]="InternalServerError"
如果使用下标设置器添加了新条目,则它将添加到字典的末尾。因此,默认情况下,字典按其最初插入的顺序包含其元素:
for(code,phrase)inresponses{print("\(code)(\(phrase))")}//(OK)//(Forbidden)//(NotFound)//(InternalServerError)
有序字典由包含键的OrderedSet以及包含其关联值的常规Array组成。可以以最小的开销提取其中的每一个元素,这是与期望某种类型的函数进行互操作的有效选择。
SwiftCollections与标准库的关系与SwiftNumerics和SwiftAlgorithms一样,Collections初期目标是提供这些新数据结构的一个试验场,最终目标则是要将这些数据结构合并到标准库中。
由于目前标准库是ABI稳定的,因此需要花大量时间考量新的数据结构哪些归类到
frozen而哪些不是,哪些方法应该是inlinable并可触及内部结构。另外Collections不仅仅是一组数据结构,如果开发人员希望进一步了解ABI设计的黑科技及完善的工具包,这也是个不错的学习资源。同时,Swift团队也鼓励开发人员积极参与到其中。由于这个软件包的重点是提供生产级数据结构的实现,因此标准也会很高,主要是