【问题标题】:Conforming Array to Equatable for certain non-equatable types对于某些非等价类型,使数组与等价一致
【发布时间】:2018-04-05 08:17:27
【问题描述】:

注意:我认为人们忽略了这个问题的重点,这不是关于我有一个元素是协议的数组,甚至可能不是关于有条件地符合 Equatable 的具体内容;这些只是我正在使用的示例。问题在于,似乎不可能多次(在不同的条件下)有条件地使某些东西符合协议。


当 Swift 4.1 宣布符合条件时,我期待数组和字典在其元素符合 Equatable 时符合。此外,我有一些自定义协议数组(称为AnyDataType),它定义了自己的比较函数,以允许在任意两个AnyDataType 变量之间进行比较,即使它们属于不同的具体类型:

protocol AnyDataType {
    func isEqual(to otherDataType: AnyDataType) -> Bool
}

我希望我可以通过添加额外的一致性使 Array<AnyDataType> 符合 Equatable

extension Array: Equatable where Element == AnyDataType {
    static func == (lhs: [AnyDataType], rhs: [AnyDataType]) -> Bool {
        ...
    }
}

不幸的是,它不起作用。当它编译时,我收到以下警告:

“Array”与协议“Equatable”的一致性已经在类型的模块“Swift”中说明

它实际上并没有使Array<AnyDataType> 符合Equatable 反正(例如,你不能比较两个[[AnyDataType]]s)。我需要做些什么不同的事情,还是这不可能?


请注意,这与它是一组协议无关。我在尝试符合一组自定义的非Equatable 结构时也遇到了同样的问题。

【问题讨论】:

  • 我不能将 AnyDataTypeEquatable 一致,因为它不允许比较 any 两个 AnyDataTypes(即,您必须知道具体类型)。
  • 这个问题与我使用协议数组的事实无关,请参阅底部的注释。我遇到的问题可能是因为 Swift 似乎不允许多个条件符合同一协议。

标签: swift generics


【解决方案1】:

根据SE-0143,事实证明这是一个有意的限制,但将来可能会允许这样做。

目前,根据所需的用途,最好的解决方案可能是:

  • 如果您想符合Equatable 以便== 可以工作,您可以直接在专用集合上实现== 而无需遵守(并为!= 添加一个实现,它只是否定结果)。这对我来说暂时还算满意。
  • 如果您想让您的类型的集合实际上符合 Equatable 而类型本身不能(因为它是一个协议),请输入erasure might be an option

【讨论】:

    【解决方案2】:

    没有办法完成你想要的。

    【讨论】:

    • 我不能将AnyDataTypeEquatable 保持一致,因为你不能这样做:var a: AnyDataType = …; var b: AnyDataType = …; a == b
    • 这是什么意思,那么:定义了自己的比较函数,允许在任意两个AnyDataType变量之间进行比较
    • 所以我有一个名为AnyDataType 的协议,并且我遵循IntStringFloat 和其他自定义结构之类的内容。如果我有两个 AnyDataType 变量,我无法使用 Equatable 比较它们,因为必须首先保证它们是相同的类型。如果 AnyDataType 符合 Equatable 变量,我什至不能拥有它,因为这是一个编译错误('Protocol AnyDataType 只能用作通用约束,因为它具有 Self 或关联的类型要求' )
    • 如果你还是不明白,尝试在 Playground 中实现你的建议;你会看到它不会编译。
    猜你喜欢
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 2021-09-25
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 1970-01-01
    相关资源
    最近更新 更多