我想测试两个Swift enum值的相等性。例如:
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那样。
斯威夫特4.1 +
正如@jedwidz指出的那样,从Swift 4.1开始(由于SE-0185, Swift还支持为枚举合成相关值的Equatable和Hashable。
因此,如果您使用的是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语句里面做嵌套开关。
斯威夫特4.1 +
正如@jedwidz指出的那样,从Swift 4.1开始(由于SE-0185, Swift还支持为枚举合成相关值的Equatable和Hashable。
因此,如果您使用的是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语句里面做嵌套开关。
在我看来,实现Equatable有点过头了。想象你有一个复杂的大枚举,有很多case和不同的参数。这些参数也都必须实现Equatable。此外,谁说你在全有或全无的基础上比较枚举案例?如果您正在测试值,并且只存根了一个特定的enum参数怎么办?我强烈建议简单的方法,比如:
if case .NotRecognized = error {
// Success
} else {
XCTFail("wrong error")
}
…或者对于参数求值:
if case .Unauthorized401(_, let response, _) = networkError {
XCTAssertEqual(response.statusCode, 401)
} else {
XCTFail("Unauthorized401 was expected")
}
在这里找到更详细的描述:https://mdcdeveloper.wordpress.com/2016/12/16/unit-testing-swift-enums/