Swift中嵌套的可选项及其数组的推断、静态和动态类型



在以下代码中,值的推断类型和动态类型之间似乎存在不一致性(超出了静态方面的预期通用性):

                            // playground values in Xcode 7.0.1 (7A1001)
                            // (same behaviour in a release build)
let oi: Int?   = nil        // nil
let ooi: Int?? = nil        // nil
let os          = [oi, ooi] // [{nil}, nil]
let anys: [Any] = [oi, ooi] // [nil, nil]
oi  == nil                  // true
ooi == nil                  // true
os[0] == nil                // false
os[1] == nil                // true
os[0].dynamicType           // Optional<Optional<Int>>.Type
os[1].dynamicType           // Optional<Optional<Int>>.Type
anys[0].dynamicType         // Optional<Int>.Type
anys[1].dynamicType         // Optional<Optional<Int>>.Type
(os[0] as Any).dynamicType  // Optional<Optional<Int>>.Type
(os[1] as Any).dynamicType  // Optional<Optional<Int>>.Type
os[0]!                      // nil
os[1]!                      // fatal error: unexpectedly found nil while unwrapping an Optional value

例如,我们不应该期望os[0].dynamicType返回Optional<Int>.Type吗?

当你看到let os = [oi, ooi] // [{nil}, nil]时,花括号很重要,因为它们表示数组的第一项确实有一个值,这个值是nil(我知道这听起来可能很奇怪)。

如果你做os.dynamicType,你会得到Array<Optional<Optional<Int>>>.Type

使用下面的代码可以更清楚:

switch os[0]
{
case .None: print("None")
case .Some(let value): print("Some")        // "Somen"
    switch value
    {
    case .None: print("None")               // "Nonen"
    case .Some(let value): print("Some")
    }
}

这也是为什么os[0]!等于nil而不会崩溃的原因。

在我看来,当您处理多个可选层时,将可选视为Struct更容易。

最新更新