如果变量类型没有显式声明,为啥在以下情况下需要可选链接? [复制]

Posted

技术标签:

【中文标题】如果变量类型没有显式声明,为啥在以下情况下需要可选链接? [复制]【英文标题】:Why optional chaining is required in the following case if the variable type is not declare explicitly? [duplicate]如果变量类型没有显式声明,为什么在以下情况下需要可选链接? [复制] 【发布时间】:2021-07-21 02:07:01 【问题描述】:

我有以下扩展名

extension UIWindow 
    static var key: UIWindow! 
        if #available(ios 13, *) 
            return UIApplication.shared.windows.first  $0.isKeyWindow 
         else 
            return UIApplication.shared.keyWindow
        
    

在以下情况下,我可以在没有可选链接的情况下使用它

案例1

UIWindow.key.addGestureRecognizer(UIGestureRecognizer())

案例2

let key: UIWindow = UIWindow.key
key.addGestureRecognizer(UIGestureRecognizer())

但是,当在以下情况下使用它时,我会得到一个编译器错误

案例 3(不工作)

let key = UIWindow.key
// value of optional type 'UIWindow?' must be unwrapped to refer to member 'addGestureRecognizer' of wrapped base type 'UIWindow'
key.addGestureRecognizer(UIGestureRecognizer())

我可以知道为什么会这样吗?为什么编译器无法将key 识别为UIWindow,而无需程序员显式声明其类型?

【问题讨论】:

【参考方案1】:

SE-054: Abolish ImplicitlyUnwrappedOptional type 中引入了此行为。关键是限制使用隐式展开的选项。

如提案所述:

如果表达式可以使用强可选类型进行显式类型检查,则可以。

因此,当没有提供其他信息时,始终首选“显式”展开的可选选项。 let key = UIWindow.key 中的 keyUIWindow? 类型。

只有当你,例如提供一个显式的类型注解: UIWindow,右侧的UIWindow? 类型将不再进行类型检查,因此编译器必须隐式解开UIWindow!

理由是:

此模型更可预测,因为它可以防止 IUO 在代码库中隐式传播,并将它们转换为强选项,默认情况下更安全。

【讨论】:

以上是关于如果变量类型没有显式声明,为啥在以下情况下需要可选链接? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Swift:如果变量 a 是非可选的,那么为啥变量 b 是可选的? [复制]

如果从数组中复制最终变量,为啥 Java 需要对最终变量进行显式强制转换?

Swift 可选(Optionals)类型

swift 可选项(Optional)

Swift之深入解析可选类型Optional的底层原理

Swift 可选绑定,为啥需要本地 var?