首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在字典/HashMap中存储KeyPaths

在字典/HashMap中存储KeyPaths
EN

Stack Overflow用户
提问于 2021-02-02 03:15:28
回答 2查看 74关注 0票数 2

我在散列ReferenceWritableKeyPath时遇到了一个问题。在对密钥路径进行散列时,散列函数似乎也将ReferenceWritableKeyPath的通用属性考虑在内。我已经包含了示例代码来说明为什么这是一个问题:

代码语言:javascript
复制
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的相同属性的路径。

这是因为第1个ReferenceWritableKeyPathValueUIColor,而第2个ReferenceWritableKeyPathValueOptional<UIColor>

我的项目要求将ReferenceWritableKeyPath存储在字典中,以便关联对象(UILabel)的每个属性只有一个keyPath。由于散列不同,这意味着相同的路径将作为两个不同的关键字存储在字典中。

有没有人知道我有什么办法可以让它正常工作?

~提前道谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-02 04:17:16

正如@Rob Napier指出的那样,问题出在泛型类型本身。我解决这个问题的方法是将doSomething拆分为两个独立的方法:

代码语言:javascript
复制
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可以是空的),将调用第一个函数。第二个函数在keyPath指向非可选属性时调用。Swift非常聪明,所以我猜它能够找出调用哪个方法,尽管它们几乎有重复的头。

票数 0
EN

Stack Overflow用户

发布于 2021-02-02 03:38:19

使textColorPath也是非可选的,以匹配:

代码语言:javascript
复制
let textColorPath = \UILabel.textColor!

或者明确说明类型:

代码语言:javascript
复制
let textColorPath: ReferenceWritableKeyPath<UILabel, UIColor> = \.textColor

潜在的问题是\.textColor是一个隐式未包装的可选项,而不是一个“真正的”可选项。在某些上下文中,它被视为底层类型,而在另一些上下文中,它被提升为可选类型。它是一个隐式取消包装的可选项的原因是,将textColor设置为nil是合法的。但您读取的值永远不会为零。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65998784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档