Swift:“类型 'any Hashable' 无法符合 'Hashable'”

8

我对在新版Xcode beta中出现的Swift语言中的any语法有些困惑。

我有一个视图,它需要使用any Hashable,而我试图将其传递给一个需要Hashable参数的参数。然而,我从Xcode中得到了这个错误:Type 'any Hashable' cannot conform to 'Hashable'。我不明白为什么会出现这种情况,因为我认为any Hashable本质上是一个类型擦除的Hashable,对吗?

这里是一个完整的代码示例,以说明我的尝试:

struct AwesomeNavigationLink: View {
    var itemToLinkTo: any Hashable
    var label: String
    
    var body: some View {
        NavigationLink(value: itemToLinkTo) {
            Text(label)
        }
    }
}

这会导致在 NavigationLink 行上出现上述错误。

我的问题是:我是否应该能够将 任何可哈希对象 传递给 可哈希对象?如果可以,如何实现,或者这是一个 bug 吗?如果不行,为什么?谢谢!


1
在最新版本的Swift/Xcode中,也存在一个错误:“使用协议'Hashable'作为类型必须写成'any Hashable'”。 - merithayan
是的,我也在想这是否是一个bug,但我想先确认一下自己是否漏掉了什么。我会稍微重新提出问题,以便更清楚地表达“是否可能”。谢谢! - merithayan
我遇到了类似的情况,因为新的NavigationSplitView更新了。 - alenm
1
any 不是一个神奇的类型擦除器。any X 的意思与 X 以前的意思完全相同,没有更多也没有更少。协议不能符合自身。 - matt
2个回答

0

我认为你看到的编译器错误让问题有点不清楚。在问题中,你声明 any Hashable 是一个类型擦除的 Hashable。然而,NavigationLinkinit 签名使用了泛型,并要求 value 是一个非常具体的类型实例,即 Hashable。这意味着 itemToLinkTo 的类型必须在编译时已知才能传递给 init,而 any Hashable 实际上是可以被哈希的任何东西,这对编译器来说是不够的。 一个解决方案可能是使你的视图也成为泛型。

struct AwesomeNavigationLink<Link: Hashable>: View {
    var itemToLinkTo: Link
    var label: String
    
    var body: some View {
        NavigationLink(value: itemToLinkTo) {
            Text(label)
        }
    }
}

这将把类型问题上移。在某个时候,必须明确并明确定义itemToLink的类型。


-3

也许@technerd的回答可以帮到你

可哈希协议(Hashable)包含了Self,而AnyHashable则没有

在协议中使用Self有点像带有泛型参数的协议,而泛型参数始终是符合类。这会导致协议无法像Set一样单独使用,因为“泛型参数”是未知的。AnyHashable通过根本不使用Self来解决这个问题,因此它现在变成了一个普通的结构体。它“擦除”了泛型Self类型。

你可以在这里阅读完整的评论 Any、Hashable、AnyHashable之间的区别


谢谢你的回答,但我指的是新的any SomeProtocol语法 - 你发布的答案是在这个关键字引入之前的情况。任何关键字已经引入了类型擦除,因此相关类型不应该成为问题。 - merithayan
"any关键字已经引入了类型擦除",不,它并没有。 - matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接