Swift 5 conversion 混淆了用法?

Swift 5 conversion confused about usage of?

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

将项目转换为 Swift 5 时,它稍微更改了代码,添加了“as [CLLocation]??”最后,我对什么是双倍感到困惑??意思是这里。 如果它会说[CLLocation]?那么我会理解这意味着该操作将 return 一个 [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]?

提前致谢

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

旧行为如下:

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

如果 Xcode 在转换为 Swift 5 时不执行任何操作,则会发生以下情况:

  1. unarchivedArrayOfObjectsreturns一个Optional<[CLLocation]>
  2. 整个try?表达式仍然是Optional<[CLLocation]>类型。
  3. 然后 if let 展开一层 OptionalcoordinatesArray 最终成为 [CLLocation].
  4. 类型

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

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

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

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