通过扩展自动合成 Swift 结构或枚举的 Equatable 一致性

Posted

技术标签:

【中文标题】通过扩展自动合成 Swift 结构或枚举的 Equatable 一致性【英文标题】:Automatic synthesis of Equatable conformance for Swift struct or enum through an extension 【发布时间】:2021-12-08 06:52:46 【问题描述】:

Swift 文档说 Equatable 一致性的自动合成可用于结构和具有关联值的枚举,只有在结构或枚举的原始定义中声明了一致性,而不是通过扩展,在这种情况下必须提供== 运算符的实现。

Documentation link

但是,下面的代码可以工作。

struct Point 
    var x: Double
    var y: Double


extension Point: Equatable 

print(Point(x: 10, y: 10) == Point(x: 5, y: 5))   // prints false

这个也是。

enum Outcome 
    case success
    case failure(reason: String)


extension Outcome: Equatable 

print(Outcome.failure(reason: "Chance") == Outcome.failure(reason: "Chance"))   // prints true

有谁知道此功能的文档记录在哪里。

谢谢。

【问题讨论】:

【参考方案1】:

综合提案 (SE-0185) 与您链接的文档有所不同:

用户必须通过将其类型声明为 Equatable 或 Hashable 来选择加入自动合成,而无需实现他们的任何要求。这种一致性必须是原始类型声明的一部分或同一文件的扩展中(以确保可以从扩展中访问 private 和 fileprivate 成员)。

根据提案,在同一个文件中声明扩展的一致性也会自动生成所需的成员,这符合实际行为。如果您在与类型不同的文件中声明扩展名,您应该会看到一条错误消息:

在声明结构 'Point' 的文件之外的扩展阻止了协议 'Equatable' 的自动综合 '=='

【讨论】:

谢谢。刚试了一下,Swift进化提案中的信息是正确的。奇怪的是,Apple 官方文档没有提供完整的信息。 developer.apple.com/documentation/swift/equatable【参考方案2】:

Equatable 一致性的自动综合可用于结构, 以及具有关联值的枚举

这意味着对于使用基本值类型的结构和枚举,无需声明与 Equatable 的显式一致性,因为它将由 Swift 本身自动提供所以

extension Point: Equatable 

没有效果。第二个例子也是如此。

conformance is declared in the original definition of the struct or enum, and not through an extension, in which case an implementation of the == operator must be provided.

这意味着对 Equatable 协议的一致性只能在声明值的模块内完成。您不能将其扩展到该模块之外以提供一致性。

您可以使用此参考了解更多详细信息 https://swiftdoc.org/v3.0/protocol/equatable/

【讨论】:

以上是关于通过扩展自动合成 Swift 结构或枚举的 Equatable 一致性的主要内容,如果未能解决你的问题,请参考以下文章

Swift21-协议

使用枚举参数自动生成的 Swift 扩展函数

Swift 常量:结构或枚举

swift 学习- 24 -- 协议 01

Swift学习Swift编程之旅---扩展(二十四)

如何区分 Swift 3.0 中的类(确定它不是结构或枚举)[重复]