Swift 集合是 Swift 编程语言数据结构实现的开源软件包。
在 swift.org 的公告中了解更多关于该软件包及其背后的意图。
该软件包目前提供以下实现:
-
Deque
,一个基于环形缓冲区的历史队列。队列为范围可替换的、可变的、随机访问集合。 -
Heap
,一个基于数组的最低最高堆,适合用作优先队列。 -
OrderedSet
,一种标准的Set
的变体,其中项目的顺序是明确定义的,并且项目可以被任意重新排序。使用ContiguousArray
作为其支持存储,并通过一个独立的哈希表进行增强,该哈希表将位打包偏移量存储到其中。 -
OrderedDictionary
,标准的Dictionary
的有序变体,提供类似的优点。 -
TreeSet
和TreeDictionary
,实现压缩哈希数组映射前缀树(CHAMP)的持久化哈希集合。它们与标准的Set
和Dictionary
类似,但在使用案例中表现得更好,这些案例中涉及共享副本的更改,提供了显著的内存节省和显著的时间提升。
以下其他数据结构目前正在开发中,但尚不稳定,无法进行预览。
SortedSet
和SortedDictionary
,由内存中持久化 B 树支持的排序集合。SparseSet
,一种常数时间集合构造,用内存换取速度。
Swift 集合使用和Swift 数值相同的模块化方法:它为每个主题组的数据结构提供一个独立模块。例如,如果您只需要一个双向队列类型,您可以通过导入DequeModule
来只引入它。OrderedSet
和OrderedDictionary
拥有许多相同的底层实现,因此它们由一个名为OrderedCollections
的单个模块提供。但是,还有一个顶级的Collections
模块,通过单个导入语句为您提供所有集合类型。
import Collections
var deque: Deque<String> = ["Ted", "Rebecca"]
deque.prepend("Keeley")
deque.append("Nathan")
print(deque) // ["Keeley", "Ted", "Rebecca", "Nathan"]
Swift Collections 包是源码稳定的。版本号遵循 语义化版本控制 -- 公共 API 的源码Breaking更改只能推出到新的大版本中。
swift-collections
包的 1.1 版本的公共 API 由在 Collections
、BitCollections
、DequeModule
、HeapModule
、OrderedCollections
和 HashTreeCollections
模块中被标记为 public
的非下划线声明组成。
不属于公共 API 的接口可以继续在任何版本中更改,包括补丁版本。如果您有一个需要使用下划线API的使用场景,请提交功能请求来描述它!我们希望公共接口尽可能有用 -- 尽管最好在不损害安全或限制未来进化的前提下。
“下划线声明”指在其完全限定名称中的任何位置都有前导下划线的声明。例如,以下是一些不被视为公共API名称的例子,即使技术上标记为公共
FooModule.Bar._someMember(value:)
(下划线成员)FooModule._Bar.someMember
(下划线类型)_FooModule.Bar
(下划线模块)FooModule.Bar.init(_value:)
(下划线初始化器)
请注意,Tests
、Utils
和 Benchmarks
子目录的内容不是公共API。我们不会对它们做出任何源代码兼容性保证 -- 它们可能会随意更改,并且在任何新版本中都可能删除代码。请勿依赖它们。
包的未来的小版本可能会根据需要更新这些规则。
我们希望这个包能迅速拥抱与其使命相关的 Swift 语言和工具链的改进。因此,时不时地,这个包的新版本要求客户升级到最新的 Swift 工具链版本。(这允许包利用新的语言/stdlib功能,建立在编译器错误修复之上,并采用包管理器的新功能,一旦它们可用。)修补(即,错误修复)版本不会增加所需的工具链版本,但是任何小版本(即,新功能)都可能这样做。
以下表格将现有的包版本映射到其最低要求的 Swift 工具链版本
包版本 | Swift 版本 | Xcode 版本 |
---|---|---|
swift-collections 1.0.x | >= Swift 5.3.2 | >= Xcode 12.4 |
swift-collections 1.1.x | >= Swift 5.7.2 | >= Xcode 14.2 |
(注意:该包没有最低部署目标,因此虽然它确实要求客户使用较新的 Swift 工具链来构建它,但代码本身能够在支持运行 Swift 代码的任何操作系统版本上运行。)
要在 SwiftPM 项目中使用这个包,您需要将其设置为包依赖项。
// swift-tools-version:5.9
import PackageDescription
let package = Package(
name: "MyPackage",
dependencies: [
.package(
url: "https://github.com/apple/swift-collections.git",
.upToNextMinor(from: "1.1.0") // or `.upToNextMajor
)
],
targets: [
.target(
name: "MyTarget",
dependencies: [
.product(name: "Collections", package: "swift-collections")
]
)
]
)
我们有一个专门的 Swift Collections 论坛,人们可以在那里探讨如何使用或工作在这个包上,以及它的进化。这也是一个讨论其进化的好地方。
如果您发现类似 bug 的问题,请提交 bug 报告!尽可能详细地填写。
我们为包的每个小版本维护独立的分支。
包版本 | 分支 |
---|---|
swift-collections 1.0.x | release/1.0 |
swift-collections 1.1.x | release/1.1 |
swift-collections 1.2.x | main |
更改必须落在它们将需要的最早发布的相应分支上。它们将定期传播到后续分支,方向如下
release/1.0
→ release/1.1
→ main
例如,任何落在 release/1.0
上的更改最终将出现在 release/1.1
和 main
上;无需为每个发布线单独提交 PR。(当前更改传播需要手动工作 -- 由项目维护者执行。)
我们有一些关于包内部结构的基础文档,这将帮助你开始。
通过提交一个pull请求,您表示您有权许可您的贡献给Apple和社区,并通过提交补丁来达成协议,您的贡献将根据Swift许可证进行许可,许可证的副本已提供在此存储库中。
- 提出一个功能请求。讨论实施它的原因。
- 提交一个包含您实现的PR,并参与审查讨论。
- 当意见达成一致,认为该特性有必要实现,并且实现运行良好、已充分测试和文档化后,它将被合并。
- 庆祝吧!
我们打算使这个包收集一般有用的数据结构——那些应该每名Swift程序员的基本工具箱中容易获取的数据结构。我们交付的实现需要有最高的技术质量,磨砺到与Swift标准库中包含的任何内容一样闪亮。(唯一的真正区别是,这个包不在正式的Swift Evolution流程中,并且其代码不是ABI稳定的。)
因此,添加一个新数据结构到这个包不是一件容易或快速的事情,并不是所有有用的数据结构都适合。
如果您有一个数据结构,认为它可能是此包的良好补充,请在论坛上发起一个主题,解释为什么您认为实现它很重要。这样我们可以弄清楚它是否适合这个包,讨论实现策略,并计划分配容量以帮助。
并非所有数据结构都达到足够高的实用性水平,以在包中发行;那些受众更窄的数据结构可能更适合作为独立包。当然,在包含特定数据结构的重要性上,合理的人可能会有不同的看法;但最终,是否接受实现的决定权在包的维护者手中。
如果维护者已经同意您的实现很可能是良好的补充,那么是时候开始工作了。一旦您准备好了可以展示的内容,就提交包含您实现的PR!我们很乐意尽早介入。从历史上看,最好的增补来自于贡献者与包维护者之间的紧密合作。
参与审查讨论,相应地调整代码。有时我们可能需要经过几个月的多次修订!这是可以的——这会让最终结果更加完美。当意见达成一致,功能已经准备好,实现已充分测试和文档化,维护者将会合并PR。这将是小型庆祝的好时机——合并是表明新加功能最终将发行的良好指标。
历史上学过,添加新数据结构的PR通常会被合并到一个新的功能分支,而不是直接合并到发布分支或main
分支,从初始合并到发布新功能的tag之间会有较长的时间间隔。没有人喜欢等待,但从可以合并的状态到可以发布的状态实现新的数据结构实际上是一项相当困难的工作,需要维护者提前安排时间和精力。实现越接近标准库的编码规范和性能基准,等待的时间可能就越短,合并和发布之间的变化也可能越少。
与Swift.org的所有项目一样,我们希望Swift Collections项目能够培育一个多样且友好的社区。我们期望贡献者遵守Swift.org行为准则。这份文档的副本可在本存储库中找到[CODE_OF_CONDUCT.md]。
这个包的当前代码项目经理是Karoy Lorentey(@lorentey)。您可以在
如果遇到监管问题,您也可以直接联系Swift核心团队的成员。