Swift Optionals – 不一致?

我有点困惑 – 我以为我理解了Optionals并且在Apple开发论坛Chris L上提到了一个解决不可变的可选问题的方法是为可选的值类型创建一个类包装器。 – 链接 !

但是以UIWindow(具有各种属性的可选类类型)为例

使用可选链接,这些属性似乎仍然不可变!

var window: UIWindow? //this works (force unwrap) self.window!.backgroundColor = UIColor.greenColor() //this optional chain doesn't work... why not? Isn't this just a safer version of the above? self.window?.backgroundColor = UIColor.redColor() 

这似乎是在beta 5中修复的!

更新Xcode beta 5


最初提出的问题已在Xcode beta5中解决,这可能会使此答案无效。


原始的anwer


可能会要求进一步解释,为什么它绝对不是不一致的行为,而是简单的无效。

可选必须始终位于实际操作数的右侧 ,并且不能位于其左侧

通过两个简单的例子看到这个逻辑:

例1

在这行代码的情况下:

 self.window?.backgroundColor = UIColor.redColor() < LEFT ^ RIGHT > 

可选项位于左侧 ,这意味着左侧可能nil因此以下操作数将在运行时出现在此处:

 nil = UIColor.redColor() 

这在任何级别上都是无效的,没有任何进一步或复杂的解释 – nil不能分配给其他东西,这就是编译器不允许的原因。

注意:self.window = nil的情况下,您可以假设逻辑行为是这样的:

 nil.backgroundColor = UIColor.redColor() 

但是关于可选链接的文档强调了一个非常重要的行为,这解释了为什么根本没有发生这种行为:

多个查询可以链接在一起,如果链中的任何链接nil整个链都会正常失败。

重点在于“整体”这个词,因此这就是为什么左侧将是nil = ...不是 nil.backgroundColor = ...正如您在Objective-C之后所期望的那样。

例2

另一个答案高度提出了如何解决它的另一个想法:

 self.window?.setBackgroundColor(UIColor.redColor()) 

为什么这样有效? 这不是一点点不一致吗? 当然不。

实际的可选项位于操作数的右侧 ,因为该行等于此行,但是我们并不打算在实践中获得void

 let result: Void! = self.window?.setBackgroundColor(UIColor.redColor()) < LEFT ^ RIGHT > 

如你所见,这里没有任何不一致,因为在self.window = nil的情况下,该行在运行时将等于这一行(请参阅上面的解释)

 let result: Void! = nil 

这将是一个完全合法的操作数。

逻辑很简单,可选项必须始终位于操作数(或运算符)的右侧 ,在左侧,它只能是非可选

可选链接用于读取值(返回值或nil ),它适用于调用方法(调用此方法或不执行任何操作)但不适用于赋值。

我相信这是设计的,但我没有看到它为什么会这样,因为这基本上是相同的:

 extension UIWindow { func setBackgroundColor(color: UIColor) { self.backgroundColor = color } } self.window?.setBackgroundColor(UIColor.redColor()) 

这没有问题。 您可以在开发论坛上报告错误或询问。 我认为这里的可选链接在逻辑上是不一致的。

您在dev论坛中的示例与此问题没有任何关系,因为该问题与值类型有关。