[英]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 相同屬性的路徑。
發生這種情況是因為第一個ReferenceWritableKeyPath
的Value
是UIColor
,而第二個ReferenceWritableKeyPath
的Value
是Optional<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.