繁体   English   中英

将 KeyPaths 存储在 Dictionary/HashMap 中

[英]Storing KeyPaths in Dictionary/HashMap

哈希ReferenceWritableKeyPath时遇到问题。 似乎 hash function 在散列密钥路径时也考虑了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 相同属性的路径。

发生这种情况是因为第一个ReferenceWritableKeyPathValueUIColor ,而第二个ReferenceWritableKeyPathValueOptional<UIColor>

我的项目需要将ReferenceWritableKeyPath存储在字典中,以便关联的 object (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, path: ReferenceWritableKeyPath<Root, T>) -> Int {
    // Do something
    print("Non-optional path:   \(path)                    \(path.hashValue)")
    return path.hashValue
}

第一个将在T是可选类型时调用,例如上面的示例(其中UIColor可以为 nil)。 当 keyPath 指向非可选属性时,第二个被调用。 Swift 非常聪明,所以我想它能够找出调用哪个方法,尽管它们几乎有重复的标题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM