Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing for enum value fails if one has associated value?

Tags:

enums

swift

I'm testing this in the Playground and I'm not sure how to do this. With a normal enum that doesn't have associated values, everything is fine.

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

var direction = CompassPoint.East

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

However, if one of my enums has an associated value, the direction test fails with this error: could not find member 'West'

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

var direction = CompassPoint.East

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

What can I do to allow for this test?

like image 318
Aaron Bratcher Avatar asked Sep 08 '14 14:09

Aaron Bratcher


People also ask

Can enum have one value?

With an enum type with only one value, most developers will not expect that (UserIDEnum)42 is used, since it's not a "defined" value of the enum. And the idea of a "magic" constant is not very good in my opinion.

What is associated value in enum?

In Swift enum, we learned how to define a data type that has a fixed set of related values. However, sometimes we may want to attach additional information to enum values. These additional information attached to enum values are called associated values.

Can enum have two same values?

1. Two enum names can have same value. For example, in the following C program both 'Failed' and 'Freezed' have same value 0.

How do you check if an enum is valid?

Enum members have to start with an alphabetic character. Specifically, I know you can use an underscore as the first char. IE, enum MyEnum { _One = 1 } is valid. Not really sure this exactly wrong, but it made the assumption that anything outside the range of '0' to '9' and '-' is a valid alphabetic character.


1 Answers

Enumerations are automatically Equatable when they have a raw value that's Equatable. In your first case, the raw value is assumed to be Int, but it would work if you'd given it another specific type like UInt32 or even String.

Once you add an associated value, however, this automatic conformance with Equatable doesn't happen any more, since you can declare this:

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

Are those equal? How should Swift know? You have to tell it, by declaring the enum as Equatable and then implementing the == operator:

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
    }
}

Now you can test for equality or inequality, like this:

let otherNorth = CompassPoint.North(2)
println(littleNorth == bigNorth)            // false
println(littleNorth == otherNorth)          // true
like image 66
Nate Cook Avatar answered Nov 11 '22 21:11

Nate Cook