小编典典

如何测试 Swift 枚举与关联值的相等性

all

我想测试两个 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 一样。


阅读 100

收藏
2022-06-16

共1个答案

小编典典

斯威夫特 4.1+

正如有帮助地指出的那样,从 Swift4.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)

在 Swift 4.1 之前

正如其他人所指出的,Swift 不会自动合成必要的相等运算符。不过,让我提出一个更清洁(恕我直言)的实现:

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 语句进行嵌套切换。

2022-06-16