背景
当我解释以下问题中的逻辑错误时:
- 如何使用guard语句来检测赋值后的nil? https://stackoverflow.com/a/36303241/4573247
我偶然发现了一个我自己无法解释的特性。
详细信息和问题
如上面的线程所示,我们可以显式地声明作用域局部不可变的类型,例如b
, in if let b = rhs ...
and guard let b = rhs ... else
子句与相同的可选类型rhs
值(试图分配给)b
,在这种情况下,“可选绑定”将始终成功:
let a: Int?
// ...
if let b: Int? = a { // will always succeed, 'Int?' to 'Int?'
print(b.dynamicType) // Optional<Int>
}
我们可以讨论是否应该允许这样做,因为这本质上是一个臃肿的块本地分配,但这不是这个问题的重点。相反,解释以下特性:
-
如果我们明确声明b
上面是隐式解包的可选类型(这里:Int!
), then b
在范围内if let
由于某种原因,子句只是一个常规的非解包可选,即Int
.
let a: Int? = nil
if let b: Int! = a {
print(b.dynamicType) // Optional<Int>
/* why not ImplicitlyUnwrappedOptional<Int> ? */
}
问题:
- Why is
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??
), e.g.
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。