首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何测试Swift枚举与关联值的相等性

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

Stack Overflow用户
提问于 2014-06-21 16:31:45
回答 12查看 99K关注 0票数 215

我想测试两个Swift枚举值是否相等。例如:

代码语言:javascript
复制
enum SimpleToken {
    case Name(String)
    case Number(Int)
}
let t1 = SimpleToken.Number(123)
let t2 = SimpleToken.Number(123)
XCTAssert(t1 == t2)

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

代码语言:javascript
复制
error: could not find an overload for '==' that accepts the supplied arguments
    XCTAssert(t1 == t2)
    ^~~~~~~~~~~~~~~~~~~

我必须定义我自己的相等操作符的重载吗?我希望Swift编译器能自动处理它,就像Scala和Ocaml做的那样。

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2014-11-03 04:18:24

Swift 4.1+

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

因此,如果你使用的是Swift 4.1或更高版本,下面的代码将自动合成必要的方法,使XCTAssert(t1 == t2)正常工作。关键是将Equatable协议添加到您的枚举。

代码语言:javascript
复制
enum SimpleToken: Equatable {
    case Name(String)
    case Number(Int)
}
let t1 = SimpleToken.Number(123)
let t2 = SimpleToken.Number(123)

在Swift 4.1之前

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

代码语言:javascript
复制
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语句中做嵌套开关。

票数 268
EN

Stack Overflow用户

发布于 2016-12-18 19:54:26

实现Equatable是一种过度的杀伤力。假设你有一个复杂而庞大的枚举,它有很多种情况和很多不同的参数。这些参数也都必须实现Equatable。此外,谁说您在全有或全无的基础上比较枚举用例?如果您正在测试值,并且只存根了一个特定的枚举参数,该怎么办呢?我强烈建议使用简单的方法,比如:

代码语言:javascript
复制
if case .NotRecognized = error {
    // Success
} else {
    XCTFail("wrong error")
}

..。或者在参数求值的情况下:

代码语言:javascript
复制
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/

票数 92
EN

Stack Overflow用户

发布于 2016-07-01 19:28:12

代码语言:javascript
复制
enum MyEnum {
    case none
    case simple(text: String)
    case advanced(x: Int, y: Int)
}

func ==(lhs: MyEnum, rhs: MyEnum) -> Bool {
    switch (lhs, rhs) {
    case (.none, .none):
        return true
    case let (.simple(v0), .simple(v1)):
        return v0 == v1
    case let (.advanced(x0, y0), .advanced(x1, y1)):
        return x0 == x1 && y0 == y1
    default:
        return false
    }
}
票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24339807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档