簡體   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