我意外地发现了以下行为:
let myIndexSet = IndexSet()
let index = myIndexSet[myIndexSet.startIndex] //index = 0
像我预料的那样,在Array
次碰撞中出现越界错误,这也是一个类似的技巧.
为什么IndexSet
允许这样做?这是我可以信赖的预期行为吗?(实际上,这对我的情况很有用)
我意外地发现了以下行为:
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条.