A-A+

Swift 5.3 预发布特性抢先看

2020年05月22日 iOS新闻资讯 暂无评论
博客主机
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 UIKitclass 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 对象。

@mainclass 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 的可用性是一个不错的选择。

//oldexecute {    let foo = self.doFirstThing()    performWork(with: self.bar)    self.doSecondThing(with: foo)    self.cleanup()}//newexecute { [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 oldValuefoo.bar = 1// This will call the getter to fetch the oldValuefoo.baz = 2

简而言之,以前总是调用属性的getter,但是从现在开始,仅当我们使用 didSet 块中的 oldValue 参数时,才调用该方法。

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

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

var numbers = Array(1...15)// Find the indices of all the even numberslet indicesOfEvens = numbers.subranges(where: { $0.isMultiple(of: 2) })// Perform an operation with just the even numberslet sumOfEvens = numbers[indicesOfEvens].reduce(0, +)// sumOfEvens == 56// You can gather the even numbers at the beginninglet 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 CFStringvar 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将包含一些社区期待已久的惊人新功能。我很高兴该语言朝着正确的方向发展。

标签:

给我留言

Copyright © ios教程,苹果粉丝,苹果资讯,ios入门教程,ios学习,ios程序员,ios视频教程,ios粉丝网 保留所有权利.   Theme  Ality

用户登录