7

I face a problem using enumeration I can't understand.

Here is declaration of an enumeration type:

enum SomeType {
    case un
    case deux
    case trois
}

Then I want to match an individual enumeration values with a if statement:

var testValue: SomeType = .trois

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

Everything is fine!

Now I want to add an associated value only to the first member value:

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

var testValue: SomeType = .trois

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

An error than appear on the if statement: Could not find member 'trois'

Does this mean enumerations can only be matched using a switchstatement?

Precisions
What I want to achieve is: "Does testValue is of member value of 'trois' with no consideration for associated value". In others words, how to match an enumeration on member value only.

Here a solution implementing Airspeed Velocity answers:

// 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")
}
0

1 Answer 1

9

Enums that don't have associated types are automatically equatable. Enums that have associated types aren't. This makes sense, because only you can know how the associated type (such as the integer that comes with your .un value) should be handled. Even though .trois doesn't have an associated type, the lack of freebie equateableness affects the whole enum. Switch works a little differently, using pattern matching, so it still works.

If you want your enum with an associated type to be equatable, you can define your own == operator:

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)
Sign up to request clarification or add additional context in comments.

5 Comments

Ok, thanks. In my understanding I thought the test was on member value and not member value + associated value. Kind of: "If the member value are the same". Some old reflexes from Ada language!
After some thinking, your answer is not what I want to achieve. I need to know if a variable match a given member value: no consideration for associated value. In other words: "Is this variable have it's member value equal to that one".
So you’re saying you want two SomeType.uns to be equal irrespective of whether their associated values are equal? In which case, just remove the where clause from the switch when defining == (i.e. do the same for .un as for .deux and .trois. But you still have to define == yourself because Swift needs to be told that’s the behaviour you want.
Yes, that's what I want to do. I have tried it and it works fine. And maybe also define === to include associated values.
@Domsware It has been a while since you wrote it, but I believe you should avoid === since it is already used for something else in Swift.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.