【发布时间】:2017-06-10 18:50:34
【问题描述】:
早在 2016 年 11 月,我发布了一个问题,询问为什么我不能使用 guard 来创建一个与可选变量同名的变量的解包版本,就像你可以使用 if let 一样:
链接:Why isn't guard let foo = foo valid?
当我写这个问题时,下面的代码将无法编译,并出现“定义与先前值冲突”的错误:
//Test of using guard to create an unwrapped version of a var, like if let
func guardTest(_ viewController: UIViewController?) -> UIViewController? {
// Check if the current viewController exists
print(String(describing: viewController))
guard let viewController = viewController else {
return nil
}
print(String(describing: viewController))
return viewController
}
但是,我刚刚发现了一些可以执行此操作的代码,它现在可以毫无怨言地编译并执行我希望它执行的操作!运行时,打印语句显示 foo 在保护之前是可选的,而在之后是未包装的可选:
viewController = Optional(<TrochoidDemo.ViewController: 0x7ff16a039a00>)
viewController = <TrochoidDemo.ViewController: 0x7ff16a039a00>
(如果你想尝试一下,我在我最新的开源项目中添加了测试功能guardTest(_:)。它可以在Github上获得,地址是https://github.com/DuncanMC/TrochoidDemo)
我很高兴这个构造现在可以按我的意愿工作,但对为什么它现在是合法的以及何时发生变化感到困惑。
是否有人知道最近对语言定义的更改使该构造在以前无法使用的地方工作?
【问题讨论】:
-
这仍然无法在函数中重新定义另一个局部变量。这似乎与 Swift 允许您创建一个与函数的输入参数同名的局部变量这一事实有关。我不知道这是否一直有效,但
var a = a现在是将输入参数转换为var的方法,因为您不能再将 var 放入函数签名中。 -
好的,为什么投反对票?如果您认为我的问题很糟糕,请解释原因。
-
我当然投了赞成票。任何挑战我认为我理解得很好的问题在我的书中都是一个很好的问题。我有点希望在否决或至少对他人的建设性评论进行投票时强迫您发表(建设性的,希望如此)评论。