Swift 5.4 发布!

Swift 5.4 现已正式发布!此版本包含各种语言和工具改进。

您可以尝试 Paul Hudson 整理的这个 playground 中的一些新功能。

上现在提供了 Swift 5.4 的更新版本《Swift 编程语言》。它也可以在 Apple Books 商店 中免费获取。

语言更新

Swift 5.4 包括以下新的语言特性

为了为新的并发模型做准备,编译器现在会针对不合格地使用 await 作为标识符发出警告和修复建议。这些标识符将在未来版本的 Swift 中被解释为关键字 await,这是 SE-0296 的一部分。

运行时性能和代码大小改进

在 Swift 5.4 中,由于更快的哈希表实现用于缓存之前的查找结果,因此运行时协议一致性检查速度显著加快。特别是,这加快了常见的运行时 as?as! 转换操作。

此外,连续的数组修改现在避免了冗余的唯一性检查。

func foo(_ a: inout [Int]) {
  // Must do copy-on-write (CoW) check here.
  a[0] = 1
  // The compiler no longer generates
  // a redundant CoW check here.
  a[1] = 2
}

最后,还有各种性能改进

Swift 包管理器更新

Swift 5.4 中的 Swift 包管理器有几个重要的更新

Windows 平台支持

Windows 上对 Swift 的支持在几个重要方面取得了进展

开发者体验改进

构建性能

代码补全

在大型函数体中,代码补全的性能现在更快得多。在 swift-package-manager 仓库中的一个示例中,对于该文件中重复调用,Swift 5.4 中 self. 的代码补全时间现在比 Swift 5.3 快 4 倍(20 毫秒 → 5 毫秒)。

代码补全在包含错误的表达式以及在没有额外上下文的情况下不明确的表达式中也更加可靠。例如,给定

func test(a: Int, b: String) -> Int { ... }
func test(a: Int, b: Int) -> String { ... }
func test(a: (Int, Int) -> Int) -> Int { ... }

对于上面的代码,代码补全现在具有以下行为

类型检查器

Swift 5.4 改进了对“链接”表达式(例如 a + b + (2 * c))的类型检查性能。例如,考虑

struct S { var s: String? }

func test(_ a: [S]) {
   _ = a.reduce("") {
     ($0 + "," + ($1.s ?? "")) + ($1.s ?? "") + ($1.s ?? "")
   }
}

对于此代码,类型检查器在 100 毫秒内完成,而以前会超时。

此外,类型检查器改进了对包含其他字面量表达式的嵌套数组字面量的性能。例如,以下无效代码以前会产生来自编译器的“在合理时间内解决过于复杂”的消息

enum E {
  case first
  case second
  case third
}

let dictionary = [
  .first: [0, 1, 2, 3, 4, 5, 6, 7],
  .second: [8, 9, 10, 11, 12, 13, 14, 15],
  .third: [16, 17, 18, 19, 20, 21, 22, 23],
]

Swift 5.4 代码现在使用精确的错误消息将此代码诊断为无效

error: reference to member 'first' cannot be resolved without a contextual type
.first : [ 0, 1, 2, 3, 4, 5, 6, 7],
 ^
error: reference to member 'second' cannot be resolved without a contextual type
 .second : [ 8, 9, 10, 11, 12, 13, 14, 15],
 ^
error: reference to member 'third' cannot be resolved without a contextual type
 .third : [16, 17, 18, 19, 20, 21, 22, 23],
 ^

类型检查器现在改进了结果构建器的诊断,包括无效语句(例如无效的 return 语句)、引用无效声明和模式匹配错误。例如

import SwiftUI

struct ContentView: View {
  @State private var condition = false

  var body: some View {
    Group {
      if condition {
        Text("Hello, World!")
          .frame(width: 300)
      } else {
        return Text("Hello, World!")
      }
    }
  }
}

对于此代码,类型检查器将报告以下错误,并提供删除 return 以应用结果构建器的 Fix-It

error: cannot use explicit 'return' statement in the body of result builder 'SceneBuilder'
 return Text("Hello, World!")
 ^

调试

在 Apple 平台上调试 Swift 代码时,具有弹性类型的变量(包括 Foundation 值类型,例如 URLURLComponentsNotificationIndexPathDecimalDataDateGlobalMeasurementUUID)再次显示在 Xcode 变量视图和 frame variable / v 命令中。