一个协议的可散列协议

Posted

技术标签:

【中文标题】一个协议的可散列协议【英文标题】:Hashable protocol for a protocol 【发布时间】:2017-02-19 19:10:40 【问题描述】:

我想知道下面的代码有什么问题?

import Foundation

enum SliderType: Int 
    case analog = 1, discrete, highLow


protocol DataEntry: class, Hashable 

    var hashValue: Int  get set  // hashable protocol requires this
    var idx: Int  get set 
    var category: String  get set 
    var sliderType: SliderType  get set 
    var sliderTitle: String  get set 
    var sliderCurrentValue: Float  get set 
    var sliderMinValue: Float  get set 
    var sliderMaxValue: Float  get set 


func ==(lhs: DataEntry, rhs: DataEntry) -> Bool 
    return lhs.idx == rhs.idx

从这个截图可以看出,我不断收到错误Protocol 'DataEntry' can only be used as a generic constraint because it has Self or associated type requirements

有人知道这里可能出了什么问题吗? 如何实现一个 Hashable 协议到一个协议?

【问题讨论】:

【参考方案1】:

== 要求 lhsrhs 是同一类型。两者都为DataEntry 类型是不够的,因为您可以将lhs 设置为FooDataEntry,将rhs 设置为BarDataEntry

您需要使用泛型来强制lhsrhs 之间的这种关系。

func ==<T: DataEntry>(lhs: T, rhs: T) -> Bool 
    return lhs.idx == rhs.idx

【讨论】:

嗯 - 仍然没有帮助。我不断收到同样的错误(即Protocol 'DataEntry' can only be used as a generic constraint because it has Self or associated type requirements...这可能是因为我使相当多的类符合DataEntryprotocol。而且这些可能不属于平等协议 - 即使你的想法引入泛型!我想我可能不得不考虑让我制作的所有类都符合DataEntry...或者你还有其他想法吗? 几乎在我使用 DataEntry 的任何地方,例如在另一个协议中:protocol BalancesModel func getEntries(_ completionHandler: @escaping (_ entries: [DataEntry]) -&gt; Void) 或在类中,例如 - 我创建属性的地方:fileprivate var entries = [DataEntry]() 嗯,是的,这是使用具有 Sef/相关类型要求的协议的结果。一旦你让DataEntry 有一个 Self 类型要求(你间接地做了我让它 Equatable,它有一个 Self 类型要求),你只能将它用作通用约束 DataEntry 现在不仅仅是一种类型,它是一种不完整的类型。对于每个可能的Self 值,它都有一个版本。例如,允许您将其直接用作类型将允许您采用两个不同的DataEntry 子类型并尝试比较它们。相等运算符只为相同类型的两个对象定义,因此不会定义。 谢谢,我猜“每一个可能的自我”部分很棘手,不是吗?我需要想想我接下来要做什么。感谢您的支持!

以上是关于一个协议的可散列协议的主要内容,如果未能解决你的问题,请参考以下文章

具有可互换属性的可散列结构?

列表不可散列,但元组可散列?

Swift 5.+ - 使类可散列?

字典和集合

自动使类可散列

Numpy 数组是可散列的吗?