简版 Swift 5.7 新特性一览

Posted 程序员大咖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简版 Swift 5.7 新特性一览相关的知识,希望对你有一定的参考价值。

👇👇关注后回复 “进群” ,拉你进程序员交流群👇👇

作者丨小集

来源丨小集(ID:zsxjtip)

Swift 5.7 引入了一个巨大的语言更改和改进集合,包括正则表达式等强大功能,if let 速记语法等生活质量改进,以及围绕 any 和 some 关键字的大量一致性清理。

在本文中,我们精简了 HACKING WITH SWIFT 的 《What’s new in Swift 5.7》一文,让大家能快速了解 Swift 5.7 的主要变化,并在此过程中提供一些动手示例,以便您自己了解发生了什么变化。

重要提示:这些变化中有许多是复杂的,其中许多也是相互关联的。如果想了解更详细的内容,可以查看原文或直接查看 SE 文档。

if let 简化语法

来源:SE-0345 https://github.com/apple/swift-evolution/blob/main/proposals/0345-if-let-shorthand.md

目标:用于将 Optional 值解包到同名的影子变量中

var name: String? = "Linda"// beforeif let unwrappedName = name     print("Hello, \\(unwrappedName)!")

=>// Swift 5.7if let name     print("Hello, \\(name)!")

多语句闭包类型推断

来源:SE-0326 https://github.com/apple/swift-evolution/blob/main/proposals/0326-extending-multi-statement-closure-inference.md

目标:提高 Swift 对闭包使用参数和类型推断的能力

结果:现在可以删除许多必须明确指定输入和输出类型的地方

let scores = [100, 80, 85]// beforelet oldResults = scores.map  score -> String in    if score >= 85         return "\\(score)%: Pass"     else         return "\\(score)%: Fail"    
// Swift 5.7let results = scores.map  score in    if score >= 85         return "\\(score)%: Pass"     else         return "\\(score)%: Fail"    

Clock, Instant 和 Duration

来源:SE-0329 https://github.com/apple/swift-evolution/blob/main/proposals/0329-clock-instant-duration.md

目标:以标准化的方式来引用 Swift 中的时间和持续时间

结果:三种时间定义

  • Clocks:表示一种测量时间流逝的方式;

  • Instants:表示一个确切的时刻;

  • Durations:表示两个 instants 之间经过了多少时间

// 新的 Task APItry await Task.sleep(until: .now +  .seconds(1), clock: .continuous)try await Task.sleep(until: .now + .seconds(1), tolerance: .seconds(0.5), clock: .continuous)

正则表达式

来源:

  • SE-0350:https://github.com/apple/swift-evolution/blob/main/proposals/0350-regex-type-overview.md

  • SE-0351:https://github.com/apple/swift-evolution/blob/main/proposals/0351-regex-builder.md

  • SE-0354:https://github.com/apple/swift-evolution/blob/main/proposals/0354-regex-literals.md

  • SE-0357:https://github.com/apple/swift-evolution/blob/main/proposals/0357-regex-string-processing-algorithms.md

目标:改进处理字符串的方式

结果:

  • 引入了一种新的 Regex 类型

  • 引入了一个结果生成器驱动的 DSL 来创建正则表达式

  • 添加了使用 /.../ 创建正则表达式的能力,而不是通过正则表达式和字符串

  • 添加了许多基于正则表达式的新字符串处理算法

示例 1:可使用的新字符串方法

let message = "the cat sat on the mat"print(message.ranges(of: "at"))print(message.replacing("cat", with: "dog"))print(message.trimmingPrefix("the "))// 同时也可使用正则表达式print(message.ranges(of: /[a-z]at/))print(message.replacing(/[a-m]at/, with: "dog"))print(message.trimmingPrefix(/The/.ignoresCase()))

示例 2:Regex 类型

do     let atSearch = try Regex("[a-z]at")        print(message.ranges(of: atSearch)) catch     print("Failed to create regex")

示例 3:DSL 语法创建正则表达式

let search3 = Regex     "My name is "
    Capture         OneOrMore(.word)
        " and I'm "
    Capture         OneOrMore(.digit)
        " years old."

示例 4:TryCapture(捕获失败或抛出错误,Swift 将自动认为整个正则表达式不匹配)

let search4 = Regex     "My name is "    Capture         OneOrMore(.word)        " and I'm "    TryCapture         OneOrMore(.digit)     transform:  match in
        Int(match)
        Capture(.digit)    " years old."

示例 5:使用具有特定类型的变量将命名匹配组合在一起

let nameRef = Reference(Substring.self)let ageRef = Reference(Int.self)let search5 = Regex     "My name is "    Capture(as: nameRef)         OneOrMore(.word)        " and I'm "
    TryCapture(as: ageRef)         OneOrMore(.digit)     transform:  match in
        Int(match)
        Capture(.digit)    " years old."if let result = greeting.firstMatch(of: search5)     print("Name: \\(result[nameRef])")    print("Age: \\(result[ageRef])")

从默认表达式进行类型推断

来源:SE-0347 https://github.com/apple/swift-evolution/blob/main/proposals/0347-type-inference-from-default-exprs.md

目标:扩展 Swift 使用泛型参数类型的默认值的能力

结果:如果你有一个泛型类型或函数,你现在可以为默认表达式提供一个具体类型

func drawLotto1<T: Sequence>(from options: T, count: Int = 7) -> [T.Element]     Array(options.shuffled().prefix(count))
print(drawLotto1(from: 1...49))print(drawLotto1(from: ["Jenny", "Trixie", "Cynthia"], count: 2))// => Swift 5.7// T 参数的默认值 1...49func drawLotto2<T: Sequence>(from options: T = 1...49, count: Int = 7) -> [T.Element]     Array(options.shuffled().prefix(count))
print(drawLotto2(from: ["Jenny", "Trixie", "Cynthia"], count: 2))print(drawLotto2())

顶层代码中的并发

来源:SE-0343 https://github.com/apple/swift-evolution/blob/main/proposals/0343-top-level-concurrency.md

目标:升级 Swift 对顶层代码的支持,支持开箱即用的并发

// 将以下代码放入 main.swift 中let url = URL(string: "https://hws.dev/readings.json")!let (data, _) = try await URLSession.shared.data(from: url)let readings = try JSONDecoder().decode([Double].self, from: data)print("Found \\(readings.count) temperature readings")

不透明的参数声明

来源:SE-0341 https://github.com/apple/swift-evolution/blob/main/proposals/0341-opaque-parameters.md

目标:解锁在使用更简单泛型的地方使用参数声明的能力

结果:[some Comparable] 参数类型 (函数可以与包含符合 Comparable 协议的一种类型的元素的数组一起使用)

func isSortedOld<T: Comparable>(array: [T]) -> Bool 
    array == array.sorted()
// => Swift 5.7func isSorted(array: [some Comparable]) -> Bool     array == array.sorted()
// Tip: 可以在显式泛型参数和这种新的更简单语法之间切换,而不会破坏您的 API

结构不透明的结果类型

来源:SE-0328 https://github.com/apple/swift-evolution/blob/main/proposals/0328-structural-opaque-result-types.md

目标:扩大不透明结果类型可以使用的地方范围

// Swift 5.7func showUserDetails() -> (some Equatable, some Equatable)     (Text("Username"), Text("@twostraws"))
func createUser() -> [some View]     let usernames = ["@frankefoster", "@mikaela__caron", "@museumshuffle"]    return usernames.map(Text.init)func createDiceRoll() -> () -> some View     return         let diceRoll = Int.random(in: 1...6)        return Text(String(diceRoll))    

为所有协议解锁 existentials

来源:SE-0309 https://github.com/apple/swift-evolution/blob/main/proposals/0309-unlock-existential-types-for-all-protocols.md

目标:放宽 Swift 对在具有 Self 或关联类型要求时将协议用作类型的禁令,转向仅基于特定属性或方法不受限制的模型

// Swift 5.7 之后合法let tvShow: [any Equatable] = ["Brooklyn", 99]for parts in tvShow     if let item = item as? String         print("Found string: \\(item)")     else if let item = item as? Int         print("Found integer: \\(item)")    

主要关联类型的轻量级同类型要求

来源:SE-0346 https://github.com/apple/swift-evolution/blob/main/proposals/0346-light-weight-same-type-syntax.md

结果:添加了更新、更简单的语法来引用具有特定关联类型的协议

protocol Cache<Content> 
    associatedtype Content

    var items: [Content]  get set     init(items: [Content])    mutating func add(item: Content)struct File     let name: Stringstruct LocalFileCache: Cache     var items = [File]()    mutating func add(item: File)         items.append(item)
    
func loadDefaultCache() -> LocalFileCache     LocalFileCache(items: [])// beforefunc loadDefaultCacheOld() -> some Cache     LocalFileCache(items: [])// Swift 5.7func loadDefaultCacheNew() -> some Cache<File>     LocalFileCache(items: [])

分布式 actor isolation

来源:

  • SE-0336: https://github.com/apple/swift-evolution/blob/main/proposals/0336-distributed-actor-isolation.md

  • SE-0344:https://github.com/apple/swift-evolution/blob/main/proposals/0344-distributed-actor-runtime.md

目标:引入 actor 以分布式形式工作的能力——使用远程过程调用 (RPC) 通过网络读取和写入属性或调用方法。

// use Apple's ClusterSystem transport typealias DefaultDistributedActorSystem = ClusterSystemdistributed actor CardCollector     var deck: Set<String>    init(deck: Set<String>)         self.deck = deck    

    distributed func send(card selected: String, to person: CardCollector) async -> Bool         guard deck.contains(selected) else  return false         do             try await person.transfer(card: selected)            deck.remove(selected)            return true         catch             return false        
    

    distributed func transfer(card: String) 
        deck.insert(card)
    

用于结果构建器的 buildPartialBlock

来源:SE-0348 https://github.com/apple/swift-evolution/blob/main/proposals/0348-buildpartialblock.md

目标:简化实现复杂结果构建器所需的重载

结果:

  • Swift 高级正则表达式支持成为可能

  • 取消了 SwiftUI 的 10-view 限制,而无需添加可变参数泛型

@resultBuilderstruct SimpleViewBuilderOld     static func buildBlock<C0, C1>(_ c0: C0, _ c1: C1) -> TupleView<(C0, C1)> where C0 : View, C1 : View         TupleView((c0, c1))        static func buildBlock<C0, C1, C2>(_ c0: C0, _ c1: C1, _ c2: C2) -> TupleView<(C0, C1, C2)> where C0: View, C1: View, C2: View         TupleView((c0, c1, c2))    

// => // Swift 5.7@resultBuilderstruct SimpleViewBuilderNew     static func buildPartialBlock<Content>(first content: Content) -> Content where Content: View         content
        static func buildPartialBlock<C0, C1>(accumulated: C0, next: C1) -> TupleView<(C0, C1)> where C0: View, C1: View         TupleView((accumulated, next))    

隐式打开的 existentials

来源:SE-0352 https://github.com/apple/swift-evolution/blob/main/proposals/0352-implicit-open-existentials.md

目标:允许 Swift 在许多情况下使用协议调用泛型函数,以消除以前存在的一个有点奇怪的障碍。

func double<T: Numeric>(_ number: T) -> T 
    number * 2let first = 1let second = 2.0let third: Float = 3let numbers: [any Numeric] = [first, second, third]for number in numbers     print(double(number))

Swift snippets

来源:SE-0356 https://github.com/apple/swift-evolution/blob/main/proposals/0356-swift-snippets.md

目标:填补项目的一个小而重要的文档空白:示例代码大于简单的 API 文档,但小于示例项目,旨在展示项目中的一个特定内容。

结果:使用 // MARK: Hide 和 // MARK: Show 隐藏一些实现细节,让读者专注于重要的部分

//! Demonstrates how to use conditional conformance//! to add protocols to a data type if it matches//! some constraint.struct Queue<Element>     private var array = [Element]()    // MARK: Hide

    mutating func append(_ element: Element) 
        array.append(element)
        mutating func dequeue() -> Element?         guard array.count > 0 else  return nil         return array.remove(at: 0)        // MARK: Showextension Queue: Encodable where Element: Encodable  extension Queue: Decodable where Element: Decodable  extension Queue: Equatable where Element: Equatable  extension Queue: Hashable where Element: Hashable  let queue1 = Queue<Int>()let queue2 = Queue<Int>()print(queue1 == queue2)

异步属性不可用

来源:SE-0340 https://github.com/apple/swift-evolution/blob/main/proposals/0340-swift-noasync.md

目标:将类型和函数标记为在异步上下文中不可用,因为以这种方式使用它们可能会导致问题,从而部分关闭了 Swift 并发模型中的潜在风险情况。

结果:要将某些内容标记为在异步上下文中不可用,请在正常选择的平台中使用 @available,然后将 noasync 添加到末尾。

@available(*, noasync)func doRiskyWork() 

其它

  • SE-0349: Unaligned Loads and Stores from Raw Memory

  • SE-0334: Pointer API Usability Improvements

  • SE-0333: Expand usability of withMemoryRebound

  • SE-0338: Clarify the Execution of Non-Actor-Isolated Async Functions

  • SE-0360: Opaque result types with limited availability

慢慢看,太难了

-End-

最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!

点击👆卡片,关注后回复【面试题】即可获取

在看点这里好文分享给更多人↓↓

以上是关于简版 Swift 5.7 新特性一览的主要内容,如果未能解决你的问题,请参考以下文章

5.7新特性

探索 Swift 5.2 的新函数式特性

第1009期TypeScript 2.4 新特性一览

Swift 3 新特性

简版 Xcode 13 新特性抢先看

MySQL 5.7新特性之Generated Column