对显式声明为“ImplicitlyUnwrappedOptional <t>”类型的不可变的可选绑定产生一个不可变类型'Optional <t>'

时间:2016-03-30 09:15:51

标签: swift

背景

当我在下面的问题中解释逻辑错误时:

我偶然发现了一个我无法解释的特殊情况。

详情和问题

如上面的主题所示,我们可以在bif let b = rhs ...子句中明确说明范围 - 本地不可变的类型,比如guard let b = rhs ... else,它们是相同的可选类型作为rhs的{​​{1}}值(尝试分配)到b,在这种情况下,“可选绑定”将始终成功:

let a: Int?

// ...

if let b: Int? = a { // will always succeed, 'Int?' to 'Int?'
    print(b.dynamicType) // Optional<Int>
}

我们可以讨论是否应该允许这样做,因为这本质上是一个膨胀的块本地分配,但这不是这个问题的重点。相反,解释以下特点:

  • 如果我们明确声明上面的b属于隐式解包的可选类型(此处为:Int!),那么b范围内的if let由于某种原因,子句只是一个常规的非解包可选项,即Int

    let a: Int? = nil
    if let b: Int! = a {
        print(b.dynamicType) // Optional<Int>
            /* why not ImplicitlyUnwrappedOptional<Int> ? */
    }
    

问题:

  • 为什么上面声明的b是一个隐式解包的可选(Int!) - 转换为“常规”可选(Int?)(在if let子句中)?

调查我自己的

我只是注意到上述“影子转换”自然不适用于对隐式展开的期权的期权的常规分配

let c: Int? = 10
let d: Int! = c
print(f.dynamicType) // ImplicitlyUnwrappedOptional<Int>

如果我们使用从非可选(if let)到隐式展开的可选(Int

的始终成功的Int!块本地赋值,则不会出现
let c = 10
if let d: Int! = c {
    print(d.dynamicType) // ImplicitlyUnwrappedOptional<Int>
}   

在以下评论中来自@Sulthan的反馈后,我们发现如果上面的a是双重可选(Int??),则不会出现此“影子转化”,例如

let a: Int?? = 10
if let b: Int! = a {
    print(b.dynamicType) // ImplicitlyUnwrappedOptional<Int>
}
if let b: Int? = a {
    print(b.dynamicType) // Optional<Int>
}

我使用的是Swift 2.2 / Xcode 7.3。

0 个答案:

没有答案