【问题标题】:Testing for enum value fails if one has associated value?如果枚举值具有关联值,则测试枚举值失败?
【发布时间】:2014-09-08 14:23:26
【问题描述】:

我正在 Playground 中对此进行测试,但不知道该怎么做。使用没有关联值的普通枚举,一切都很好。

enum CompassPoint {
    case North
    case South
    case East
    case West
}

var direction = CompassPoint.East

if direction != .West {
    println("Go West!")
}

但是,如果我的其中一个枚举具有关联值,则方向测试会失败并出现以下错误:找不到成员“West”

enum CompassPoint {
    case North(Int)
    case South
    case East
    case West
}

var direction = CompassPoint.East

if direction != .West {
    println("Go West!")
}

我能做些什么来允许这个测试?

【问题讨论】:

    标签: enums swift


    【解决方案1】:

    当枚举具有Equatable 的原始值时,它们会自动成为Equatable。在您的第一种情况下,原始值假定为 Int,但如果您将其指定为另一种特定类型,例如 UInt32 甚至 String,它将起作用。

    然而,一旦你添加了一个关联的值,这种与Equatable 的自动一致性就不会再发生了,因为你可以这样声明:

    let littleNorth = CompassPoint.North(2)
    let bigNorth = CompassPoint.North(99999)
    

    它们相等吗?斯威夫特应该怎么知道?您必须通过将enum 声明为Equatable 然后实现== 运算符来告诉它:

    enum CompassPoint : Equatable {
        case North(Int)
        case South
        case East
        case West
    }
    
    public func ==(lhs:CompassPoint, rhs:CompassPoint) -> Bool {
        switch (lhs, rhs) {
        case (.North(let lhsNum), .North(let rhsNum)):
            return lhsNum == rhsNum
        case (.South, .South): return true
        case (.East, .East): return true
        case (.West, .West): return true
        default: return false
        }
    }
    

    现在您可以测试是否相等或不等,如下所示:

    let otherNorth = CompassPoint.North(2)
    println(littleNorth == bigNorth)            // false
    println(littleNorth == otherNorth)          // true
    

    【讨论】:

    • 返回 true 的案例可以合并为一个案例:case (.South, .South), (.East, .East), (.West, .West): return true
    • 由于SE-0185,从Swift 4.1 开始,Swift 还支持为具有关联值的枚举合成EquatableHashable
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多