我想测试两个Swift枚举值的相等性.例如:

enum SimpleToken {
    case Name(String)
    case Number(Int)
}
let t1 = SimpleToken.Number(123)
let t2 = SimpleToken.Number(123)
XCTAssert(t1 == t2)

但是,编译器不会编译等式表达式:

error: could not find an overload for '==' that accepts the supplied arguments
    XCTAssert(t1 == t2)
    ^~~~~~~~~~~~~~~~~~~

我必须定义自己的相等运算符重载吗?我希望Swift编译器能像Scala和Ocaml一样自动处理它.

推荐答案

Swift 4.1+

正如@jedwidz所指出的,从Swift 4.1(由于SE-0185),Swift还支持为带有关联值的枚举合成EquatableHashable.

因此,如果您使用的是Swift 4.1或更新版本,以下内容将自动合成必要的方法,以便XCTAssert(t1 == t2)种方法都能正常工作.关键是将Equatable协议添加到枚举中.

enum SimpleToken: Equatable {
    case Name(String)
    case Number(Int)
}
let t1 = SimpleToken.Number(123)
let t2 = SimpleToken.Number(123)

Before Swift 4.1

正如其他人所指出的,Swift不会自动合成必要的等式运算符.不过,让我提出一个更清洁(IMHO)的实施方案:

enum SimpleToken: Equatable {
    case Name(String)
    case Number(Int)
}

public func ==(lhs: SimpleToken, rhs: SimpleToken) -> Bool {
    switch (lhs, rhs) {
    case let (.Name(a),   .Name(b)),
         let (.Number(a), .Number(b)):
      return a == b
    default:
      return false
    }
}

这远非理想——有很多重复——但至少你不需要在内部使用if语句进行嵌套切换.

Swift相关问答推荐

如何在HStack中均匀分布视图?

更改正在进行的异步任务的完成(SWIFT并发)(&q;)?

RealityKit如何获得两个相对大小相同的ModelEntity?

如何在SWIFT中解码Instagram Backup中的字符串?

.onReceive NSWindow.CloseNotify是否会为App中的每个窗口调用?

在visionOS RealityView中使用.GenerateText时,未显示Reality Composer Promaterial 纹理

SWIFT:使字典数组值可变

修改数组中每个类实例的属性

NavigationStack 和 TabView - 工具栏和标题不显示

SwiftUI:按钮的圆形边缘的边框尺寸加倍

在 Swift 的异步上下文中,如何指示我想要函数的同步版本?

如何在 SwiftUI 中用图像替换占位符文本?

在 Select 器上显示alert Select SwiftUI

如何让 UIKit 挤压你的视图,使其适合屏幕

RxSwift:share() 替代方案,保证upstream 的单一订阅

如何使被拖动的对象成为前景(foreground)对象

Swiftwhere数组扩展

协议扩展中的where self是什么

在 Swiftui 中是否有一种简单的方法可以通过捏合来放大图像?

URLComponents.url 为零