使用if语句匹配枚举的错误

时间:2014-12-18 19:23:58

标签: swift enumeration swift-playground

我使用枚举时遇到问题我无法理解。

这是枚举类型的声明:

enum SomeType {
    case un
    case deux
    case trois
}

然后我想将单个枚举值与if语句匹配:

var testValue: SomeType = .trois

if testValue == .trois {
    // Do something
}

一切都很好!

现在我只想将关联值添加到第一个成员值

enum SomeType {
    case un(Int)
    case deux
    case trois
}

var testValue: SomeType = .trois

if testValue == .trois {
    // Do something
}

if声明中显示的错误:Could not find member 'trois'

这是否意味着只能使用switch语句匹配枚举?

精密工业
我想要实现的目标是:" testValue是否具有' trois'的成员价值?不考虑相关价值"。换句话说,如何仅在成员值上匹配枚举。

这是一个实施Airspeed Velocity答案的解决方案:

// Test equality only on member value
func == (lhs:SomeType, rhs:SomeType) -> Bool {
    switch (lhs, rhs) {
    case (.un(let lhsNum), .un(let rhsNum)):return true
    case (.deux, .deux): return true
    case (.trois, .trois): return true
    default: return false
    }
}

// Test equality on member value AND associated value
func === (lhs:SomeType, rhs:SomeType) -> Bool {
    switch (lhs, rhs) {
    case (.un(let lhsNum), .un(let rhsNum)) where lhsNum == rhsNum: return true
    case (.deux, .deux): return true
    case (.trois, .trois): return true
    default: return false
    }
}

var testValue = SomeType.un(3)


// Tests

if testValue == .un(1) {
    println("Same member value")
}


if testValue === .un(3) {
    println("Same member value AND same associated contents")
}

1 个答案:

答案 0 :(得分:9)

没有关联类型的枚举会自动相等。具有关联类型的枚举不是。这是有道理的,因为只有你可以知道如何处理相关类型(例如你的.un值附带的整数)。尽管.trois没有相关类型,但缺乏免费赠品等同性会影响整个枚举。使用模式匹配,Switch的工作方式略有不同,因此它仍然有效。

如果您希望具有关联类型的枚举具有相同性,则可以定义自己的==运算符:

enum SomeType {
    case un(Int)
    case deux
    case trois
}

// possibly there's a more succinct way to do this switch
func ==(lhs: SomeType, rhs: SomeType) -> Bool {
    switch (lhs,rhs) {
    case let (.un(i), .un(j)) where i == j: return true
    case (.deux,.deux): return true
    case (.trois, .trois): return true
    default: return false
    }
}

var testValue: SomeType = .trois

if testValue == .trois {
    println("equals .trois")
}

// note, for SomeType to work with generic
// functions that require Equatable, you have
// to add that too:
extension SomeType: Equatable { }

// which means this will work:
let a: [SomeType] = [.un(1), .deux, .trois]
find(a, .trois)