我想测试两个 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 一样。
正如有帮助地指出的那样,从 Swift4.1 开始(由于SE-0185,Swift 还支持综合Equatable和Hashable具有关联值的枚举。
Equatable
Hashable
因此,如果您使用的是 Swift 4.1 或更高版本,以下内容将自动合成必要的方法,以便XCTAssert(t1 == t2)有效。关键是将Equatable协议添加到您的枚举中。
XCTAssert(t1 == t2)
enum SimpleToken: Equatable { case Name(String) case Number(Int) } let t1 = SimpleToken.Number(123) let t2 = SimpleToken.Number(123)
正如其他人所指出的,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 语句进行嵌套切换。