Swift 为什么IndexSet说即使新元素已经在集合中,也会插入新元素?

Swift 为什么IndexSet说即使新元素已经在集合中,也会插入新元素?,swift,set,Swift,Set,使用Sets,我可以方便地在集合中插入一个元素,还可以通过调用insert,检查该元素是否在集合中: let array = [1,2,3,4,4,2,5,3,6,7,1] var set = Set<Int>() for item in array { // set.insert not only inserts the item, but also tells me whether the item was in set before the insert if

使用
Set
s,我可以方便地在集合中插入一个元素,还可以通过调用
insert
,检查该元素是否在集合中:

let array = [1,2,3,4,4,2,5,3,6,7,1]
var set = Set<Int>()
for item in array {
    // set.insert not only inserts the item, but also tells me whether the item was in set before the insert
    if set.insert(item).inserted {
        print("Encountered new item: \(item)")
    } else {
        print("\(item) has already been encountered!")
    }
}
但是,如果我使用
IndexSet
重写相同的逻辑:

let array = [1,2,3,4,4,2,5,3,6,7,1]
var set = IndexSet()
for item in array {
    // set.insert not only inserts the item, but also tells me whether the item was in set before the insert
    if set.insert(item).inserted {
        print("Encountered new item: \(item)")
    } else {
        print("\(item) has already been encountered!")
    }
}
输出变为:

Encountered new item: 1
Encountered new item: 2
Encountered new item: 3
Encountered new item: 4
Encountered new item: 4
Encountered new item: 2
Encountered new item: 5
Encountered new item: 3
Encountered new item: 6
Encountered new item: 7
Encountered new item: 1
看来
IndexSet.insert
返回的元组总是匹配
(true,)
,但即使如此,集合的
计数也不会增加。我必须在插入之前检查
set.contains(item)
,以生成所需的输出

问题:这是
索引集的预期行为吗


我知道
IndexSet
是一个CocoaAPI,不是Swift的原生版本,所以我想
IndexSet
可能有一些特殊的语义,关于两个数字“相同”的含义,我不知道。我还在bugs.swift.org上查找了关于
IndexSet
,但没有找到任何关于
insert
始终返回true的信息。

IndexSet
NSIndexSet
NSMutableIndexSet
的swift值覆盖类型。从中的实现中可以看出,
IndexSet
上的所有操作都被转发到
NS(可变)IndexSet

// Temporary boxing function, until we can get a native Swift type for NSIndexSet
@inline(__always)
mutating func _applyMutation<ReturnType>(_ whatToDo : (NSMutableIndexSet) throws -> ReturnType) rethrows -> ReturnType {

    // ...
}

因此
IndexSet.insert(value)
调用
NSMutableIndexSet.add(value)
,如果索引集不存在,则将新值添加到索引集中。只要索引是唯一的,它的行为是正确的,但是
inserted
返回值总是
true

与您的问题无关,但是为什么不简单地
如果设置了。insert(item)。inserted{
@LeoDabus Gosh…我现在觉得自己很愚蠢。我可能在写这篇文章的时候想到了Haskell…这是一个非常奇怪的行为。我不知道为什么IndexSet总是返回true,但工作正常。啊,所以
NSMutableIndexSet
不允许我们确定元素是否首先插入。一种简单的方法“回报真相“只是简单地计算插入之前和插入后集合中元素的数量,对吗?还是因为某些原因而不能工作/不是最佳的?”清扫员:是的,NSMutable索引集不返回该信息。-我不知道这将是多么有效,因为Objy-C基金会类型不是开源的。您可以提交一个bug报告。
// Temporary boxing function, until we can get a native Swift type for NSIndexSet
@inline(__always)
mutating func _applyMutation<ReturnType>(_ whatToDo : (NSMutableIndexSet) throws -> ReturnType) rethrows -> ReturnType {

    // ...
}
/// Insert an integer into the `IndexSet`.
@discardableResult
public mutating func insert(_ integer: Element) -> (inserted: Bool, memberAfterInsert: Element) {
    _applyMutation { $0.add(integer) }
    // TODO: figure out how to return the truth here
    return (true, integer)
}