我想测试两个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那样。
对于枚举和结构,似乎没有编译器生成的相等操作符。
例如,如果你创建了自己的类或结构来表示一个复杂的数据模型,那么这个类或结构的“等于”的含义就不是Swift能帮你猜出来的。”[1]
要实现相等性比较,可以这样写:
@infix func ==(a:SimpleToken, b:SimpleToken) -> Bool {
switch(a) {
case let .Name(sa):
switch(b) {
case let .Name(sb): return sa == sb
default: return false
}
case let .Number(na):
switch(b) {
case let .Number(nb): return na == nb
default: return false
}
}
}
[1]参见https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html#//apple_ref/doc/uid/TP40014097-CH27-XID_43的“等价运算符”
另一种方法使用if大小写加逗号,在Swift 3中有效:
enum {
case kindOne(String)
case kindTwo(NSManagedObjectID)
case kindThree(Int)
static func ==(lhs: MyEnumType, rhs: MyEnumType) -> Bool {
if case .kindOne(let l) = lhs,
case .kindOne(let r) = rhs {
return l == r
}
if case .kindTwo(let l) = lhs,
case .kindTwo(let r) = rhs {
return l == r
}
if case .kindThree(let l) = lhs,
case .kindThree(let r) = rhs {
return l == r
}
return false
}
}
我是这样写我的项目的。但我不记得我是怎么想到的。(我刚刚谷歌了一下,但没有看到这样的用法。)任何意见都将不胜感激。