【问题标题】:Swift: Protocol X as a type cannot conform to 'Hashable'Swift:作为一种类型的协议 X 不能符合“可哈希”
【发布时间】:2021-11-05 10:38:30
【问题描述】:

我想做这样的事情:

enum TestEnum {
    case all
    case some(_ testElements: Set<TestElement>)
}

public protocol TestElement: Hashable {
    var identifier: String { get }
}

但我收到此错误:

Protocol 'TestElement' 作为类型不能符合 'Hashable'

我能做什么?谢谢你的帮助

【问题讨论】:

  • 如果我有两个TestElements,具有相同的identifier,但它们的类型不同。你想让他们在同一个集合中吗?
  • @Sweeper 我现在明白这个问题了,谢谢。

标签: swift enums hashable


【解决方案1】:

我不确定你想用 TestEnum 做什么,但我建议使用一个额外的元素来重写它,它是 TestClass 的实例,这样你就可以符合 TestEnum.some 。代码如下:

    enum TestEnum {
    case all
    case some(_ testElements: Set<TestClass>)
}

public protocol TestElement: Hashable {
    var identifier: String { get }
}

struct TestClass: TestElement {
    var identifier: String
    //needed to conform to Equatable
    static func == (lhs: TestClass, rhs: TestClass) -> Bool {
        return true
    }
}

还有一个更简单、更优雅的解决方案,它使用 TestElement 作为结构,而不是协议。我会亲自推荐这种方法。代码如下:

    enum TestEnum {
    case all
    case some(_ testElements: Set<TestElement>)
}

public struct TestElement: Hashable {
    public private (set) var identifier: String
}

【讨论】:

  • 你了解协议的优势吗?
  • @JoakimDanielson 但是协议类型不能符合协议,因为只有具体类型才能符合协议。我错了吗?
  • 不,但这不是我的意思。 OP 希望使用一种协议,以便他们可以将枚举用于不同类型,因此建议使用非协议、仅一种类型的解决方案类型未达到目标。
  • 好的,我现在明白了。我只是从解决错误的角度看待这个问题,而不是解决他的问题。
【解决方案2】:

就像之前提到的那样:两个具体类型不能在同一个集合中(如果集合被定义为协议,这是允许的),因为不清楚如何比较它们。因此,在使用该集合时,您必须在该集合中拥有一个具体的单一类型。

所以你可以这样做:

enum TestEnum<T: TestElement> {
    case all
    case some(_ testElements: Set<T>)
}

public protocol TestElement: Hashable {
    var identifier: String { get }
}

也就是说:您的协议保持原样,并且要定义枚举,您不需要任何具体类型。您还可以限制 Set 中的元素以符合 TestElement 协议,就像您打算的那样。但是当你要使用枚举时,你必须确定集合将使用的实际类型。

例如如果你有class Person: TestElement {...,你可以像这样使用枚举:

let persons = Set<Person>()
TestEnum<Person>.some(persons)

看到一篇很好的文章here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    相关资源
    最近更新 更多