当设置为属性时,Swift enum会丢失初始化值吗?

当设置为属性时,Swift enum会丢失初始化值吗?,swift,enums,switch-statement,Swift,Enums,Switch Statement,我已经找到了一个解决办法,但这个问题让我很烦恼,我想我会和大家分享,以防其他人也有同样的问题。我很想知道为什么会这样。在下面的代码中,当枚举是局部变量时,我可以在类初始值设定过程中很好地打开它。我将枚举值存储到属性中。但是,当我尝试在下例中的另一个方法(名为bar())中打开存储属性(名为foo)时,我会收到编译器警告和一个错误,即无法识别成员。它似乎知道foo是MyEnum类型,但不知道.ABC、.DEF和.GHI是成员 enum MyEnum { case ABC, DEF, GH

我已经找到了一个解决办法,但这个问题让我很烦恼,我想我会和大家分享,以防其他人也有同样的问题。我很想知道为什么会这样。在下面的代码中,当枚举是局部变量时,我可以在类初始值设定过程中很好地打开它。我将枚举值存储到属性中。但是,当我尝试在下例中的另一个方法(名为bar())中打开存储属性(名为foo)时,我会收到编译器警告和一个错误,即无法识别成员。它似乎知道foo是MyEnum类型,但不知道.ABC、.DEF和.GHI是成员


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")

        }
    }
}
解决方法是说:

switch foo as MyEnum { }
或者在方法中声明一个局部变量,如

let x : MyEnum = foo

switch x {  }

再一次,我很高兴找到了一个解决办法,但我肯定想知道这是否是预期的行为,或者是否需要向苹果提交雷达。这是Xcode 6.2,顺便说一句。

属性
foo
不是
MyEnum
,而是
隐式的附加属性
aka
MyEnum。与许多其他情况不同,
开关
不会隐式展开它

您必须手动将其展开:

    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")
    }
或使用
强制展开
如果您确定
foo
不是
nil
,则:

    switch foo! {
    case .ABC: println("ABC foo")
    case .DEF: println("DEF foo")
    case .GHI: println("GHI foo")
    default: println("no foo")
    }
或按原样隐式地与
匹配:

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

原因是
MyEnum
MyEnum是不同的类型。请参见:要么您必须在
bar()
中展开
foo
,要么使用普通属性(而不是隐式展开属性)。啊,隐式展开属性是可选的。还没有在代码中签出它,但它是有意义的。谢谢