我意外地发现了以下行为:

let myIndexSet = IndexSet()
let index = myIndexSet[myIndexSet.startIndex] //index = 0

像我预料的那样,在Array次碰撞中出现越界错误,这也是一个类似的技巧.

为什么IndexSet允许这样做?这是我可以信赖的预期行为吗?(实际上,这对我的情况很有用)

推荐答案

这似乎是一个bug——它直接与Collection中记录的行为相矛盾.

Collection.subscript(Index) -> Element的文档说明了其参数:

要访问的元素的位置.position必须是集合的有效索引,该索引不等于endIndex属性.

但以下打印0:

let myIndexSet = IndexSet()
print(myIndexSet[myIndexSet.endIndex])

请注意,索引集is为空,如其count表示为isEmpty属性,并且其startIndex等于其endIndex.

print(myIndexSet.count) // 0
print(myIndexSet.isEmpty) // true
print(myIndexSet.startIndex == myIndexSet.endIndex) // true

查看swift-corelibs-foundation implementation中的源代码,我们可以确切地看到原因:

public subscript(index : Index) -> Element {
    return index.value
}

它不判断自身是否为空.此下标的返回值仅取决于index!看看责任,这一行代码是6年前添加的,从那以后就没有人更改或报告这个bug.我猜"这不应该奏效,但确实奏效"比"这应该奏效,但没有奏效"更不容易找到:

从那以后,我已经发布了this bug report条.

Swift相关问答推荐

如何在一个角色隔离类上编写自定义==实现?

为SwiftUI文本视图提供固定宽度,并仅在文本换行时使文本视图底部增大

插入/删除视图时的Swiftui动态过渡

如何在枚举有关联数据时使用combined if with case

同时具有每个文本的标识符的文本组的可扩展性标识符

KMM-Swift铸造密封类

有条件地在同一视图上设置两个不同的过渡

使用序列初始化字符串的时间复杂度是多少?

如何使用可搜索在搜索栏中搜索包括>或<?

如何在 macOS/AppKit 的窗口选项卡上接受拖动项目的放置?

使用 RxSwift 围绕 async/await 方法创建 Observable

动画偏移正在 destruct 按钮 SwiftUI

签署GoogleSignIn-GoogleSignIn需要开发团队

如何在 SwiftUI 中正确实现Collection 夹?

引用类型(类)不需要但 struct 需要的可识别 id

Swift - 如何更新多目录中的对象

临时添加到视图层次 struct 后,Weak view引用不会被释放

当我必须在 Swift 中的类、 struct 和枚举之间进行 Select 时,我应该如何推理?

不支持用作符合协议 AnyObject 的具体类型

playground 导入:没有这样的模块Foo