1

I've found a work-around, but this problem is vexing me and I thought I'd share in case anyone else is having the same problem. Would love to know why this is happening. In the code below, I can switch on the enum just fine during the class initializer when it's a local variable. I store the enum value into a property. But when I try to switch on the stored property (named foo) in a different method (named bar()) in the example below - I get compiler warnings and an error that the member(s) are not recognized. It seems to know that foo is a MyEnum type, but doesn't know that .ABC, .DEF, and .GHI are members.


enum MyEnum {
    case ABC, DEF, GHI
}

class MyClass : NSObject {

    var foo : MyEnum!

    convenience init(foo: MyEnum) {

        self.init()

        self.foo = foo

        switch foo {

        case .ABC: println("ABC foo")
        case .DEF: println("DEF foo")
        case .GHI: println("GHI foo")
        default: println("no foo")

        }
    }

    func bar() {

        switch foo {

        case .ABC: println("ABC foo")
        case .DEF: println("DEF foo")
        case .GHI: println("GHI foo")
        default: println("no foo")

        }
    }
}

The workaround is to either say:

switch foo as MyEnum { }

or declare a local variable in the method like

let x : MyEnum = foo

switch x {  }

Again, glad I found a workaround, but would sure like to know if this is the expected behavior or if a radar needs to be filed with Apple. This is Xcode 6.2, BTW.

jay492355
  • 594
  • 5
  • 12
  • 1
    Reason is that `MyEnum` and `MyEnum!` are different types. See this: http://stackoverflow.com/questions/24018327/what-does-an-exclamation-mark-mean-in-the-swift-language Either you have to unwrap `foo` in `bar()`, or use normal property (and not implicitly unwrapped one). – 0x416e746f6e Mar 20 '15 at 07:16

1 Answers1

4

Property foo is not MyEnum, but ImplicitlyUnwrappedOptional<MyEnum> aka MyEnum!. Unlike many other cases, switch does not implicitly unwrap it.

You have to unwrap it manually:

    if let foo = foo {
        switch foo {
        case .ABC: println("ABC foo")
        case .DEF: println("DEF foo")
        case .GHI: println("GHI foo")
        default: println("no foo")
        }
    }
    else {
        println("nil foo")
    }

OR force unwrap with ! if you are sure foo is not nil, :

    switch foo! {
    case .ABC: println("ABC foo")
    case .DEF: println("DEF foo")
    case .GHI: println("GHI foo")
    default: println("no foo")
    }

OR match with ImplicitlyUnwrappedOptional<Enum> as is:

    switch foo {
    case .Some(.ABC): println("ABC foo")
    case .Some(.DEF): println("DEF foo")
    case .Some(.GHI): println("GHI foo")
    default: println("no foo")
    }
rintaro
  • 51,423
  • 14
  • 131
  • 139