首页 > 解决方案 > Swift 5 转换对使用感到困惑?

问题描述

我使用下面的代码将 CLLocation 数组存储在 UserDefaults 中以取消归档它。

将项目转换为 Swift 5 时,它稍微更改了代码,添加了“as [CLLocation]??” 最后,我对双倍感到困惑?这里的意思。如果它会说[CLLocation]?那么我会理解这意味着该操作将返回一个 [CLLocation] 数组或 nil。

但是,我不确定如何解释 [CLLocation]??。我知道合并如何正常工作,但在这种情况下我不知道。

这是 swift 5 之前的代码:

if let coordinatesArray = try? NSKeyedUnarchiver.unarchivedArrayOfObjects(ofClass: CLLocation.self, from: coordinatesArrayData) {
  return coordinatesArray
}

这是在更新之后。

if let coordinatesArray = ((try? NSKeyedUnarchiver.unarchivedArrayOfObjects(ofClass: CLLocation.self, from: coordinatesArrayData)) as [CLLocation]??) {
  return coordinatesArray
}

谁能解释如何解释 [CLLocation]?

提前致谢

标签: swiftswift5

解决方案


的行为try?在 Swift 5 中发生了变化,如SE-0230中所述。如果 " " 后面的表达式try?是可选类型,则不会再添加可选层。由于您正在转换旧代码,Xcode 尽量不破坏它,通过将其包装回双可选来保持旧行为。

旧行为如下:

  1. unarchivedArrayOfObjects返回一个Optional<[CLLocation]>
  2. try?接受它旁边的表达式的类型,并将它Optional<[CLLocation]>包装在另一个中Optional,所以你得到Optional<Optional<[CLLocation]>>,又名[CLLocation]??.
  3. 然后if let展开一层Optional, 并coordinatesArray最终成为类型Optional<[CLLocation]>

如果 Xcode 在转换为 Swift 5 时什么都不做,就会发生这种情况:

  1. unarchivedArrayOfObjects返回一个Optional<[CLLocation]>
  2. 整个try?表达式仍然是 type Optional<[CLLocation]>
  3. 然后if let展开一层OptionalcoordinatesArray最终成为 type [CLLocation]

如您所见,您的代码现在返回完全不同的类型。Xcode 将其包装在另一层可选项中,以至少保持类型相同。

(
    (
        try? NSKeyedUnarchiver.unarchivedArrayOfObjects(ofClass: CLLocation.self, from: coordinatesArrayData)
    )
    as [CLLocation]??
)

不过,这仍然不会与您的旧代码具有相同的行为。我认为将演员表放在try?表达式中应该会产生相同的行为:

try? (
    NSKeyedUnarchiver.unarchivedArrayOfObjects(ofClass: CLLocation.self, from: coordinatesArrayData) 
    as [CLLocation]??
)

推荐阅读