Swift 5.3 预发布特点抢先看

Tibor Bodecs · 2020-05-18
本文来自 知识小集 ,作者 Tibor Bodecs

image.png

作者 | Tibor Bodecs 
来源 | https://theswiftdev.com/

Swift 5.3将是一个令人高兴的新版本。这篇文章展示了最新的 Swift 特点。

从 Apple 在 3 月下旬公布 Swift 5.3 发布流程至今,5.3 分支上曾经完成了很多新功能。假设你想懂得一下都有甚么新功能,可以应用 swiftenv 装置最新快照来体验一下。

Package Manager 更新

Swift Package tool 5.3 版本引入了一些异常好的功能。

资本

随着 SE-0271 的完成,Swift Package Manager 终究可以将资本文件与代码打包在一路。我信赖这是一个异常受迎接的新功能,由于有些库须要嵌入资产文件,但今朝为止 SPM 还没法支撑。

本地化资本

SE-0278 扩大了资本支撑,经过过程此完成,可认为 Swift 软件包声明本地化的资本。SE-0278 的描陈述清楚明了提议的详细信息,假设须要随包一路发布本地化文件,可以看看。

二进制依附

另外一个很棒的任务是 SPM 终究将可以或许应用二进制依附项。SE-0272添加了此功能,是以假设欲望供给闭源的人如今可以应用此功能。如许可以在给定的途径或地位设置 binaryTarget 依附性,并且可以将二进制文件用于库或或履行文件。

条件目标依附

SE-0273 供给了一个很好的弥补,可以应用基于给定平台的依附项。这意味着在为特定平台构建产品时,可以将产品用于一个 target。

以上功能是对 SPM 的重要弥补,欲望 Xcode 也能从这些功能中受益,并且我们还将在即将发布的 IDE 版本中看到一些严重年夜的新的加强功能。

说话特点

5.3 版本中引入了很多风趣的新提议。

多个尾随闭包

SE-0279 是争议最大年夜的新提案之一。当我第一次看到它时,我不肯定能否须要它,为甚么有人会花这么大年夜的力量清除一些括号呢?

import UIKit

class ViewController: UIViewController {

   override func viewDidLoad() {
       super.viewDidLoad()

       // old
       UIView.animate(withDuration: 0.3, animations: {
         self.view.alpha = 0
       }, completion: { _ in
         self.view.removeFromSuperview()
       })
       // still old
       UIView.animate(withDuration: 0.3, animations: {
         self.view.alpha = 0
       }) { _ in
         self.view.removeFromSuperview()
       }

       // new
       UIView.animate(withDuration: 0.3) {
         self.view.alpha = 0
       }
       
       UIView.animate(withDuration: 0.3) {
           self.view.alpha = 0
       } completion: { _ in
           self.view.removeFromSuperview()
       }
   }
}

如你所见,这主如果一种语法糖,然则我压服本身具有它是很好的。

为罗列类型分解 Comparable

由于 SE-0266,Enum 类型不用显式完成 Comparable 协定。

enum Membership: Comparable {
   case premium(Int)
   case preferred
   case general
}
([.preferred, .premium(1), .general, .premium(0)] as [Membership]).sorted()

Comparable 协定是主动分解的,就像其它类型的 Equatable 和 Hashable 一样。固然,假设须要,您可以供给本身的完成。

罗列的 case 完成协定

Swift 的罗列是功能强大年夜构建基块,如今它们变得更好了。

protocol DecodingError {
 static var fileCorrupted: Self { get }
 static func keyNotFound(_ key: String) -> Self
}

enum JSONDecodingError: DecodingError {
 case fileCorrupted
 case keyNotFound(_ key: String)
}

SE-0280 的重要目标是消除现无限制,假设罗列供给的 case 其定名和参数能符合协定的请求,则罗列可以作为协定的一个完成。

基于类型的法式榜样出口点

SE-0281为我们供给了一个新的 @main 属性,可以应用该属性来定义应用法式榜样的出口点。这是一个很好的弥补,不用再编写 MyApp.main() 办法,而只需用main属性标记 MyApp 对象。

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

   static func main() {
       print("App will launch & exit right away.")
   }
}

不推荐应用UIApplicationMain和NSApplicationMain属性,而推荐应用@main,我敢打赌这将鄙人一个重要版本中发布...

多形式 Catch

SE-0276 是另外一种语法糖,异常便利同时捕获多个异常。

do {
   try performTask()
}
catch TaskError.someRecoverableError {
   recover()
}
catch TaskError.someFailure(let msg), TaskError.anotherFailure(let msg) {
   showMessage(msg)
}

这清除在 catch 块中应用 switch case。

Float16

SE-0277 将 Float16 添加到标准库中。

let f16: Float16 = 3.14

泛型数学函数也行将推出...

Self 的改变

SE-0269 aka。关于那些不太情愿写 self 的人来讲,在不太能够产生援用轮回时进步@escaping 闭包中隐式 self 的可用性是一个不错的选择。

//old
execute {
   let foo = self.doFirstThing()
   performWork(with: self.bar)
   self.doSecondThing(with: foo)
   self.cleanup()
}

//new
execute { [self] in
   let foo = doFirstThing()
   performWork(with: bar)
   doSecondThing(with: foo)
   cleanup()
}

这将许可我们仅将self写入捕获列表,而稍后在块内将其忽视。

完美 didSet 语义

SE-0268 是一个底层改进,使 didSet 行动更佳,更靠得住。

class Foo {
   var bar = 0 {
       didSet { print("didSet called") }
   }

   var baz = 0 {
       didSet { print(oldValue) }
   }
}

let foo = Foo()
// This will not call the getter to fetch the oldValue
foo.bar = 1
// This will call the getter to fetch the oldValue
foo.baz = 2

简而言之,之前总是调用属性的getter,然则从如今开端,仅当我们应用 didSet 块中的 oldValue 参数时,才调用该办法。

在非持续元素上添加集合操作

SE-0270 添加了一个 RangeSet 类型来表示多个不持续的范围,和用于创建和应用范围集的各类集合操作。

var numbers = Array(1...15)

// Find the indices of all the even numbers
let indicesOfEvens = numbers.subranges(where: { $0.isMultiple(of: 2) })

// Perform an operation with just the even numbers
let sumOfEvens = numbers[indicesOfEvens].reduce(0, +)
// sumOfEvens == 56

// You can gather the even numbers at the beginning
let rangeOfEvens = numbers.moveSubranges(indicesOfEvens, to: numbers.startIndex)
// numbers == [2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15]
// numbers[rangeOfEvens] == [2, 4, 6, 8, 10, 12, 14]

该建议还经过过程一些应用RangeSet类型的API办法扩大了Collection类型,假设您常常应用范围,则应当看看。

高低文范型声明的 where子句

假设仅援用泛型参数,则应用 SE-0267 可以完成函数并在其上施加where束缚。推敲以下代码段:

protocol P {
   func foo()
}

extension P {
   func foo() where Self: Equatable {
       print("lol")
   }
}

这在老版本上没法编译,然则在 Swift 5.3 以后它将像魔术一样任务。

添加可拜访未初始化存储的字符串初始化器

SE-0263 添加了一个新的String初始化器,使您可以应用未初始化的缓冲区。

let myCocoaString = NSString("The quick brown fox jumps over the lazy dog") as CFString
var myString = String(unsafeUninitializedCapacity: CFStringGetMaximumSizeForEncoding(myCocoaString, ...)) { buffer in
   var initializedCount = 0
   CFStringGetBytes(
       myCocoaString,
       buffer,
       ...,
       &initializedCount
   )
   return initializedCount
}
// myString == "The quick brown fox jumps over the lazy dog"

经过过程应用这类新的init办法,您不用再担心不安然的指针了。

Swift的将来生长

今朝,在Swift的开辟面板上还有6个被接收的提案,个中一个正在接收审核。Swift 5.3将包含一些社区等待已久的惊人新功能。我很高兴该说话朝着精确的偏向生长。