【问题标题】:Why force unwrapping is required in case of enum and switch?为什么在枚举和切换的情况下需要强制展开?
【发布时间】:2016-02-13 18:01:02
【问题描述】:

我注意到奇怪的 swift 行为,因为在我看来,颜色变量不应该在下面写的 switch 的情况下被强制解包,但是没有解包编译器会显示一条错误消息。

enum Colours: Int {
case Red = 0, White, Black
}

var colours: Colours!
colours = .Red

switch colours! { // <-- why I have to unwrap colours? As you can see colours are declared as '!'
case .Red: break
default: break
}

如果颜色变量未解包,编译器会向我显示该错误:

在我看来这是快速的不一致,有人有什么想法吗?

【问题讨论】:

    标签: ios swift enums


    【解决方案1】:

    更新:这已在 Swift 5.1 中得到修复。来自CHANGELOG

    SR-7799:

    现在可以将枚举案例与可选枚举进行匹配,而无需使用“?”在模式的末尾。

    这也适用于您的隐式展开选项的情况:

    var colours: Colours!
    
    switch colours {
    case .red:
        break    // colours is .red
    default:
        break    // colours is .white, .black or nil
    }
    

    上一个答案:

    switch 语句中使用时,即使是隐式展开 选项不会自动解包。 (一个原因可能是你 否则无法将它们与nil 匹配。)

    所以你必须解开(要么用 colours! 如果colours == nil 或使用可选绑定将崩溃,或者 - 或者 - 匹配 .Red? 这是.Some(.Red)的快捷方式:

    var colours: Colours!
    
    switch colours {
    case .Red?:
        break    // colours is .Red
    default:
        break    // colours is .White, .Black or nil
    }
    

    同样适用于其他模式匹配表达式,例如

    if case .Red? = colours {
        // colours is .Red 
    } else {
        // colours is .White, .Black or nil
    }
    

    这也与枚举类型无关,仅与隐式有关 在模式中展开的选项:

    let x : Int! = 1
    
    switch x {
    case nil:
        break // x is nil
    case 1?:
        break // x is 1
    default:
        break // x is some other number
    }
    

    【讨论】:

    • 您的一些colourscolors ;-)
    • 是的!自动更正也在更正我的评论。不过,责任可能真的属于诺亚韦伯斯特。 :-)
    【解决方案2】:

    而不是使用:

    var colours: Colours!
    colours = .Red
    

    简单地使用

    var colours = Colours.Red
    

    这应该可以解决问题。

    【讨论】:

    • 但我想要可选的颜色变量。它应该没有'!'在我看来。
    • @roher 将枚举类型变量声明为可选并不是很有用,因为枚举被设计为具有明确的状态。使用 .None 状态或类似状态,而不是可选状态。
    【解决方案3】:

    这是因为您创建了 colours 变量,如可选类型。如果你这样做:

    var colours: Colours
    colours = .Red
    

    你不必解开这个值

    如果我们看一下可选类型是什么,我们会发现这是枚举:

    enum Optional<T> {
        case Some(T)
        case None
    }
    

    它可以是Some 例如IntNone,在这种情况下它的值为零。

    当你这样做时:

    var colours: Colours!
    

    ! 直接指示您这不是Colours 类型,而是enum ImplicitlyUnwrappedOptional&lt;Colours&gt; 类型。在创建的那一刻,它将是Some&lt;Colours&gt;,如果它的值相等,但是有了这个!,你就知道它是enum ImplicitlyUnwrappedOptional&lt;Colours&gt;,在下一个时刻它将是None。这就是为什么你必须在switch 中使用!

    您的colours 值是ImplicitlyUnwrappedOptional&lt;Colours&gt; 类型,它可能是Coloursnil,您必须在`switch` 中直接指出这是Colours 类型。

    【讨论】:

    • 您能否提供一些文档说明使用! 声明变量使其成为可选变量?
    • colors 的类型为 ImplicitlyUnwrappedOptional&lt;Colours&gt;,而不是 Optional&lt;Colours&gt;
    • @MartinR 是的,你是对的,我更正了,谢谢你的评论
    猜你喜欢
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多