为什么相同的代码会在一个位置抛出错误而不是另一个?

时间:2017-01-04 23:52:45

标签: swift swift3

我目前正在开始一个项目的工作,我的第一个任务是分解其他人从AppDelegate创建的God Object。我已经开始复制与管理位置相关的代码,以便将对该代码的调用委托给新对象。

然而,有两个声明让我感到疯狂。

新文件:

if locationManager?.location?.horizontalAccuracy > horizontalAccuracyCheck{...}

旧文件:

if locationManager?.location?.horizontalAccuracy > horizontalAccuracyCheck{...}

您会注意到代码是相同的。在两种情况下self.locationManager?定义为:

var locationManager: CLLocationManager?

但是在新文件中,我收到了有关可选类型的值的警告,没有打开' - 为什么?完全重复的代码,复制&粘贴,会有什么不同?

更改代码以解包它修复了一些问题:

if (locationManager?.location?.horizontalAccuracy)! > horizontalAccuracyCheck{...}

我可以解决为什么我需要显式展开潜在的可选返回。但是......为什么只在一个地方?

2 个答案:

答案 0 :(得分:3)

原因是我们在这里谈论两种完全不同的语言。一个文件是Swift 2,另一个文件是Swift 3。

在Swift 2中,您可以使用大于或小于运算符将表示数字的可选项与另一个数字进行比较。在Swift 3中,你无法做到这一点。

这是一个更简单的例子:

    let optint : Int? = 7
    let ok = optint < 42

该代码在Swift 2中是合法的,但在Swift 3中是非法的。

答案 1 :(得分:2)

正如所讨论的in this Q&A - Swift迁移器将插入自定义fileprivate运算符重载,以允许可选比较在Swift 3中的工作方式与在Swift 2中的方式相同。因为此重载是fileprivate,您将无法在项目中任何其他未定义它的源文件中使用它,因此您的比较无法在新的源文件中进行编译。

因此,一种解决方案就是将其复制到新文件中。另一种方法是删除fileprivate访问修饰符。重载将默认为internal,因此模块中的其他Swift文件可以访问。

虽然我真的只是建议完全删除重载,而是在出现时编写自己的显式逻辑进行可选比较 - 过载很容易被滥用(如Swift evolution proposal所示,将其删除)。 / p>