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

Swift 为什么相同的代码会在一个位置抛出错误,而不会在另一个位置抛出错误?,swift,swift3,Swift,Swift3,我目前正在启动一个项目,我的第一个任务是分解其他人从AppDelegate创建的God对象。我首先复制了与位置管理相关的代码,目的是将对该代码的调用委托给新对象 然而,我有两种说法让我发疯 新文件: if locationManager?.location?.horizontalAccuracy > horizontalAccuracyCheck{...} 旧文件: if locationManager?.location?.horizontalAccuracy > horizon

我目前正在启动一个项目,我的第一个任务是分解其他人从AppDelegate创建的God对象。我首先复制了与位置管理相关的代码,目的是将对该代码的调用委托给新对象

然而,我有两种说法让我发疯

新文件:

if locationManager?.location?.horizontalAccuracy > horizontalAccuracyCheck{...}
旧文件:

if locationManager?.location?.horizontalAccuracy > horizontalAccuracyCheck{...}
您会注意到代码是相同的。在这两种情况下,self.locationManager?定义如下:

var locationManager: CLLocationManager?
但是在新文件中,我得到了一个关于“可选类型值no unwrapped”的警告——为什么?完全重复的代码,复制并粘贴,是什么让这有所不同

将代码更改为“展开”可以修复以下问题:

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

我可以想一想为什么我需要显式地打开一个潜在的可选返回。但是为什么只有一个地方?

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

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

下面是一个简单的例子:

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

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

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

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

下面是一个简单的例子:

    let optint : Int? = 7
    let ok = optint < 42
let optint:Int?=7.
让ok=optint<42
该代码在Swift 2中是合法的,但在Swift 3中是非法的。

如前所述–Swift migrator将插入一个自定义的
fileprivate
操作符重载,以便允许进行可选的比较,以便在Swift 3中以与在Swift 2中相同的方式工作。由于此重载是
fileprivate
,您将无法从项目中未定义它的任何其他源文件中使用它,因此您的比较无法在新的源文件中编译

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

尽管我真的建议完全删除重载,并在出现重载时编写自己的显式逻辑以进行可选比较,但重载很容易被误用(如要删除它的示例所示).

如前所述–Swift migrator将插入一个自定义的
fileprivate
操作符重载,以便允许进行可选的比较,以便在Swift 3中使用与在Swift 2中相同的方法。由于此重载是
fileprivate
,您将无法从项目中未定义它的任何其他源文件中使用它,因此您的比较无法在新的源文件中编译

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


尽管我真的建议完全删除重载,而不是编写自己的显式逻辑,以便在出现时进行可选比较——重载太容易被误用(如图所示),无法删除它。

您是说相同的项目可以同时在Swift2和Swift3中?有趣的是,我猜您是在将这个项目迁移到Xcode 8,从而迁移到Swift 3之后继承的。可以对一个目标执行迁移,但不能对另一个目标执行迁移。此外,多种方案可能会使情况复杂化。另外,我的记忆是,当迁移第一次发生时,您甚至可以基于每个文件进行迁移(关于迁移的信息保存在项目文件中,您看不到)。我需要看看这个项目,以便更好地猜测这种情况是如何发生的。但我猜这些文件从未迁移到Swift 3,但默认情况下,您的新文件是在Swift 3中。确切地说,是我迁移的。这就是我最初加入的目的——新文件是在迁移之后创建的。那么,听起来旧文件没有被迁移。然而,也可能是您看到了编译器的一个小故障:尝试退出Xcode并清空派生数据文件,看看事情是否平衡。我在迁移后看到了一些奇怪的不一致。文件肯定被迁移了,我已经在另一个问题上清除了派生数据。有些奇怪的事情正在发生,不知道发生了什么,但如果这是“预期”行为,那就不是工作追踪。你是说同一个项目可以在Swift2和Swift3中进行?有趣的是,我猜您是在将这个项目迁移到Xcode 8,从而迁移到Swift 3之后继承的。可以对一个目标执行迁移,但不能对另一个目标执行迁移。此外,多种方案可能会使情况复杂化。另外,我的记忆是,当迁移第一次发生时,您甚至可以基于每个文件进行迁移(关于迁移的信息保存在项目文件中,您看不到)。我需要看看这个项目,以便更好地猜测这种情况是如何发生的。但我猜这些文件从未迁移到Swift 3,但默认情况下,您的新文件是在Swift 3中。确切地说,是我迁移的。这就是我最初加入的目的——新文件是在迁移之后创建的。那么,听起来旧文件没有被迁移。然而,也可能是您看到了编译器的一个小故障:尝试退出Xcode并清空派生数据文件,看看事情是否平衡。我看到了一些奇怪的矛盾