如何解决在 Dictionary/HashMap 中存储 KeyPath
我在对 ReferenceWritableKeyPath
进行哈希处理时遇到问题。哈希函数似乎在对密钥路径进行哈希处理时也考虑了 ReferenceWritableKeyPath
的通用属性。我已经包含示例代码来说明为什么这是一个问题:
struct TestStruct<T> {
// This function should only be callable if the value type of the path reference == T
func doSomething<Root>(object: Root,path: ReferenceWritableKeyPath<Root,T>) -> Int {
// Do something
print("Non-optional path: \(path) \(path.hashValue)")
return path.hashValue
}
}
let label = UILabel()
let textColorPath = \UILabel.textColor
let testStruct = TestStruct<UIColor>()
let hash1 = testStruct.doSomething(object: label,path: \.textColor)
let hash2 = textColorPath.hashValue
print("Optional path: \(textColorPath) \(hash2)")
如果你运行上面的代码,你会注意到 hash1 和 hash2 是不同的,尽管它们是 UILabel 相同属性的路径。
发生这种情况是因为第一个 ReferenceWritableKeyPath
的 Value
为 UIColor
,而第二个 ReferenceWritableKeyPath
的 Value
为 Optional<UIColor>
我的项目要求将 ReferenceWritableKeyPath
存储在字典中,以便关联对象 (UILabel) 的每个属性只有一个 keyPath。由于哈希值不同,这意味着相同的路径将在字典中存储为 2 个不同的键。
有没有人知道我可以让它工作的方法?
~提前致谢
解决方法
使 textColorPath
也是非可选的,以匹配:
let textColorPath = \UILabel.textColor!
或者明确说明类型:
let textColorPath: ReferenceWritableKeyPath<UILabel,UIColor> = \.textColor
潜在的问题是 \.textColor
是一个隐式展开的可选项,而不是“真正的”可选项。在某些上下文中被视为基础类型,而在其他上下文中它被提升为 Optional。它是一个隐式解包可选的原因是因为将 textColor
设置为 nil 是合法的。但是你读到的值永远不会为零。
正如@Rob Napier 指出的,问题出在泛型类型本身。我解决问题的方法是将 doSomething
拆分为两个单独的方法:
func doSomething<Root>(object: Root,path: ReferenceWritableKeyPath<Root,T?>) -> Int {
// Do something
print("Non-optional path: \(path) \(path.hashValue)")
return path.hashValue
}
func doSomething<Root>(object: Root,T>) -> Int {
// Do something
print("Non-optional path: \(path) \(path.hashValue)")
return path.hashValue
}
第一个将在 T
是可选类型时被调用,例如在上面的示例中(其中 UIColor
可以为零)。当 keyPath 指向一个非可选属性时,第二个被调用。 Swift 非常聪明,所以我猜它能够找出调用哪个方法,尽管它们几乎有重复的标头。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。