swift 新特性 - WWDC22

type
status
date
slug
summary
tags
category
icon
password
这个 session 介绍了 swift 相关的新特性。
 
相关文档:

Swift Packages 更新

Trust on first use (TOFU)

  • 新的安全协议,其中在首次下载包时记录包的指纹
  • 后续下载将验证此指纹,如果指纹不同,则报告错误

插件

Xcode 插件又回归了,记得 Xcode8 之前有 IDE 插件,很多丰富好用的插件,后来苹果更新了新版 Xcode 之后,插件被取消了,现在终于又可以在 Xcode 中使用。新版本提供有两种类型的插件,一种是命令插件,可以修改代码,用于注释自动生成,格式调整等,另一种是 Build Plugin,在构建时注入额外步骤,比如源代码生成或者资源处理。更详细的内容,可以看这个 session。 Meet Swift Package plugins 和 Create Swift Package plugins。 插件被声明在 package 下一个名为 plugins 文件夹中,插件被视为 swift 可执行文件。

命名冲突

当两个独立的包具有同名模块时,会产生命名冲突,现在 swift 允许在包外使用 moduleAliases 字段重命名,这样可以解决模块重名的问题。

Swift 底层性能优化

  • 编译时间提升
    • 更快的泛型类型检查
  • 运行时改进
    • Swift5.7 会对协议一致性检查进行缓存,提高编译速度。
  • Swift driver(Swift 编译器驱动程序)
    • Xcode 现在已经将 Swift driver 集成到构建系统内部,而不是一个独立的可执行文件,提高了项目构建速度。

Swift 并发模型

安全检查

Swift 5.5 引入了新的并发模型,Swift 5.7 主要针对数据竞争安全对并发模型进行了完善。Swift 并发模型支持 macOS 10.15、iOS 13、tvOS 13 和 watchOS 6 以上系统。 开发者现在可以通过在 Build Settings 中设置 Strict Concurrency Checking 来体验安全检查。在 swift 6 中,如果开发者在两个线程中都修改了同一个值,并且没有使用 actor,应该出现报错。

distributed Actors

关键字 distributed 可以用来修饰 actor 和 actor 的方法,表明 actor 可能部署在远端机器上。
分布式的 actor 方法执行可能会由于网络原因失败,所以在外部调用 actor 方法时需要在 await 前面加上关键字 try。如果想要了解更多可以参考 Meet distributed actors in Swift

其他优化

Async Algorithms Package 苹果开源了用于处理 AsyncSequence 的算法,使跨平台部署更加灵活。 Actor 会执行优先级最高的任务,同时并发模型内置了防止优先级反转的机制,来确保低优先级任务不会阻塞高优先级任务。 Instruments 中新增了工具 Swift Concurrency,帮助开发者排查性能问题。提供了一整套工具来帮助可视化和优化并发代码。可以参考 Visualize and optimize Swift concurrency

Swift 语言优化

If let 简写优化

之前我们是这样写的:
现在我们可以这样写:
但是这种写法不能扩展到对象的属性,也就是说不能这样写:

返回类型推断

在 swift 5.7 之前,我们需要在闭包中显式的指定返回类型,比如:
但现在,swift 可以自动推断类型,我们可以省略返回类型:

允许指针类型转换

针对从外部引入的方法和函数,Swift 支持在 C 语言中合法的指针类型转换,以下情况将不会再有报错。
notion image

正则表达式

Swift 5.7 引入了和正则表达式相关的大量改进,极大的改进了我们处理字符串的方式。 我们从易到难来使用一下,首先新增了一些字符串方法, 例如:
一样看去好像没什么区别,他们的优势在于接受正则表达式:
除了支持正则表达式的字符串,swift 还提供了一个专用的正则表达式类型,就像这样工作:
但这里有一个地方需要注意,我们使用字符串初始化 Regex 类型,swift 会在运行时解析这个字符串,不能在编译时替我们检查正则表达式是否有效,但是我们使用像 message.ranges(of: /[a-z]at/) 这种方式时,是在编译时检查,这种方式相对更安全一些。 除此以外,swift 更是给我们提供了一种 DSL 语法让我们能够初始化 Regex,例如:
并且如果我们使用 TryCapture 替代 Capture,swift 会自动根据是否匹配而捕获失败或者抛出错误。
我们甚至可以使用特定类型和已经命名的匹配规则绑定在一起,比如:
以上就是新的正则匹配的语法,我个人偏向使用 regex 字面量的形式,在支持 swift6 的 Xcode 中,在 Other Swift Flags 中添加“-Xfrontend -enable-bare-slash-regex”来启用这种语法。

基于默认表达式的类型推断

在 Swift 5.7 之前,不支持为泛型参数提供默认值,因为在现有语法规则下,默认值的类型必须在任何调用场景都有效才行。Swift 5.7 提供了一种基于默认表达式的类型推断方式,使得可以为泛型参数添加默认值。如果想要了解更多可以参考 Type inference from default expressions

不透明的参数声明

在 swift5.7 中,我们可以在一些使用简单泛型的地方使用一些参数声明。 比如下面这个例子,我们想要编写一个检查数组是否排序的函数,可以这样写:
这段函数和下面这段函数等价,是一种新的语法糖:

返回不透明的泛型

现在我们可以一次返回多个不透明类型:
还可以返回不透明类型数组:
或者调用一个函数,这个函数在调用的时候返回一个不透明类型:

总结

以上就是我比较关注的 swift5.7 的一些新特性,当然并不完整,除了以上这些,还可以在 Swift Evolution 页面搜索 5.7 查看 Swift 5.7 相关变更。

其他

时间标准

Swift 5.7 引入了一种新的标准方式来获取和表示时间,可分为以下三个部分: 1.Clock: 表示当下,并且能提供在将来特定时间点唤起的功能 2.Instant: 表示某个瞬间 3.Duration: 用于计量流逝的时间 Clock 有 ContinuousClock 和 SuspendingClock 两种内置时钟,ContinuousClock 在系统休眠时也会保持时间递增,而 SuspendingClock 则不会。Task 休眠相关的 API 也会根据新标准有所更新。如果想要了解更多可以参考 Clock, Instant, and Duration

基于默认表达式的类型推断

在 Swift 5.7 之前,不支持为泛型参数提供默认值,因为在现有语法规则下,默认值的类型必须在任何调用场景都有效才行。Swift 5.7 提供了一种基于默认表达式的类型推断方式,使得可以为泛型参数添加默认值。如果想要了解更多可以参考 Type inference from default expressions
 
notion image
  • 📕 小红书/即刻:@轻舟
  • ☕ 如果我的内容有帮助到你,可以请我喝杯咖啡,这将鼓励我为你创造更多有价值的内容。
Buy Me A Coffee
  • Giscus

© 轻舟 2017-2024