gpt4 book ai didi

swift - set on swift 语言的问题

转载 作者:搜寻专家 更新时间:2023-10-31 22:24:36 25 4
gpt4 key购买 nike

我创建了一个采用Hashable 协议(protocol)的类。

所以我创建了这个类的一些具有不同属性的实例,并将它们添加到 Set 中。

然后我更改对象的属性。

此更改后,Set 有时会失败.contains(以及.remove)。在调试器检查器中,我看到该对象与 Set 中的元素具有相同的内存地址。那么为什么会随机失败呢?请注意,我总能找到集合中元素的索引。

我用 playground(在 xcode10 上)测试了几次,每次执行结果都会改变。

class Test: Hashable {
// MARK: Equatable protocol
static func == (lhs: Test, rhs: Test) -> Bool {
return lhs === rhs || lhs.hashValue == rhs.hashValue
}

var s: String
func hash(into hasher: inout Hasher) {
hasher.combine(s.hashValue)

}
init(s: String) {
self.s = s
}
}

func test(s: Set<Test>, u: Test) -> Bool {
if s.contains(u) {
print("OK")
return true
} else {
print("FAIL") // SOMETIMES FAIL
if !s.contains(u) {
if let _ = s.firstIndex(where: { $0 == u }) {
print("- OK index") // ALWAYS OK
return true
} else {
print("- FAIL index") // NEVER FAIL
return false
}
} else {
return true
}
}
}

var s: Set<Test> = []
let u1 = Test(s: "a")
s.insert(u1)
let u2 = Test(s: "b")
s.insert(u2)
test(s: s, u: u2)

u2.s = "c"
test(s: s, u: u2)
u2.s = "d"
test(s: s, u: u2)
u2.s = "b"
test(s: s, u: u2)

最佳答案

来自docs在 NSSet 上:

If mutable objects are stored in a set, either the hash method of the objects shouldn’t depend on the internal state of the mutable objects or the mutable objects shouldn’t be modified while they’re in the set.

我认为这完全涵盖了这种情况。没错,它是关于 Cocoa NSSet 的,但我希望 Swift Set 在这方面与 NSSet 相对应。

仅作记录,我能够重现您描述的行为,消除一些更糟糕或更可疑的代码 - 不是在 Playground 上,使用 == 的合法实现并使用 hashValue,并且没有不必要地调用 test 函数:

class Test: Equatable, Hashable, CustomStringConvertible {
var s: String
static func == (lhs: Test, rhs: Test) -> Bool {
return lhs.s == rhs.s
}
var hashValue: Int {
return s.hashValue
}
init(s: String) {
self.s = s
}
var description: String {
return "Test(\(s))"
}
}

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

var s: Set<Test> = []
let u1 = Test(s: "a")
s.insert(u1)
let u2 = Test(s: "b")
s.insert(u2)

print(s.contains(u2))
u2.s = "c"
print(s.contains(u2))
}
}

要对其进行测试,请一遍又一遍地运行该项目。有时你会得到 true true,有时你会得到 true false。不一致表明您不应该改变集合中的对象。

关于swift - set on swift 语言的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52968978/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com