swift3到swift5_Swift5 3迈向性能和质量

swift3到swift5

The last stable release of SwiftLang was 5.2.3 which came in April 2020 and 5.3 is ready to make its apperance as it is in the stage of development and the release branch has already been created. The least to expect in the WWDC announcements this year is that Xcode 12 will include Swift 5.3 🤯. Let’s dive in to see what’s in this pre-release package 🚀

SwiftLang的最后一个稳定版本是2020年4月的5.2.3,而5.3已准备就绪,因为它处于开发阶段,并且已经创建了发行​​分支。 在今年的WWDC公告中,人们最不希望看到的是Xcode 12将包含Swift 5.3让我们 深入 了解一下此 预发布 软件包中的内容what

Within these efforts, the language is expanding the availability and support of Swift for Windows and additional Linux distributions. Swift now offers downloadable toolchain and docker images for various Linux distributions.

在这些努力中,该语言正在扩展Windows版 Swift 和其他Linux发行版的可用性和支持。 Swift现在为各种Linux发行版提供可下载的工具链和docker映像

Image for post

But will the Windows or Linux developers actually switch to Swift for development over .NET languages? 🤔

但是Windows或Linux开发人员是否真的会切换到Swift进行.NET语言开发? 🤔

Support of SwiftUI on Windows can surely fuel the adoption of Swift cross-platform packages. Let’s see if Apple has any plans around SwiftUI to give developers another reason to migrate to Swift with this amazing declarative way of creating UI.

Windows上对SwiftUI的支持肯定会推动Swift跨平台软件包的采用。 让我们看看苹果公司是否有关于SwiftUI的计划,以这种惊人的声明式创建UI的方式,为开发人员提供另一个迁移到Swift的理由。

Swift Package Manager具有更多功能 (More power to Swift Package Manager)

资源资源 (Resources)

Until now, libraries that have embedded assets were not able to add SwiftPM support. Apple has finally accepted the proposal of adding bundle resource files alongside code in Swift Package Manager. With the implementation of Swift Evolution SE-0271, we now have a consistent way of accessing the resources (images, data files, and other resources needed at runtime) from the source code in the package. 😎

到目前为止,具有嵌入式资产的库还无法添加SwiftPM支持。 苹果最终接受了在Swift Package Manager中将捆绑资源文件与代码一起添加的建议。 借助Swift Evolution SE-0271的实现 ,我们现在有了一种一致的方式,可以从包中的源代码访问资源(图像,数据文件以及运行时所需的其他资源)。 😎

本地化资源— SE-0278 (Localized Resources — SE-0278)

How amazing would it be if we could also ship localized resources as part of SwiftPM 🧐?

如果我们还可以将本地化资源作为SwiftPM part的一部分提供,那会有多神奇?

Good news, we can now define localized versions of resources in the SwiftPM manifest and have them automatically accessible at runtime using the same Foundation Bundle APIs.

好消息,我们现在可以在SwiftPM清单中定义资源的本地化版本,并使用相同的Foundation Bundle API在运行时自动访问它们。

二进制依赖 (Binary Dependencies)

Prior to Swift 5.1, the Swift compiler itself did not expose all the features(like ABI compatibility) required for building a workable solution. Since those features are present now, it makes sense to re-evaluate the role of binary packages.

在Swift 5.1之前,Swift编译器本身并未提供构建可行解决方案所需的所有功能(如ABI兼容性 )。 由于这些功能现在已经存在,因此有必要重新评估二进制程序包的作用。

Implementation of SE-0272 has made it possible to have a binary target dependency at a given path or location and you can use the binary as a product in a library or executable.

SE-0272的实现使在给定路径或位置具有二进制目标依赖关系成为可能,并且您可以将二进制文件用作库或可执行文件中的产品。

We have been using existing package managers like CocoaPod to rely on closed source dependencies like Firebase, Google Analytics, and many more. Guess what! We can now easily integrate closed libraries with SwiftPM that do not deliver source code.

我们一直在使用现有的包管理器(例如CocoaPod)来依赖诸如Firebase,Google Analytics(分析)之类的封闭源代码依赖项。 你猜怎么了! 现在,我们可以轻松地将不提供源代码的封闭库与SwiftPM集成在一起。

Image for post

It has also paved a way for existing code base which would like to integrate “simply” with SwiftPM, but require more complicated build processes.

它还为现有代码库铺平了道路,该代码库希望“简单”地与SwiftPM集成,但是需要更复杂的构建过程。

条件目标依赖 (Conditional Target Dependencies)

Well, we are aware that the packages which span over multiple platforms may need to depend on different libraries depending on the platform. Here comes yet another nice addition with the development of SE-0273, we can now use dependencies based on the target platform.

好吧,我们知道跨多个平台的软件包可能需要依赖于不同的库,具体取决于平台。 SE-0273的开发带来了另一个不错的补充,我们现在可以基于目标平台使用依赖项。

语言功能更新 (Language Feature Updates)

多个尾随闭包 (Multiple Trailing Closures)

It’s not hard to guess why trailing closures have gained so much popularity 😄. We know the call site is easier to read, it is more concise and less nested, without loss of clarity.

不难猜测为什么尾随的闭包如此受欢迎。 我们知道,呼叫站点更容易阅读,更简洁,嵌套更少,并且不会造成任何损失。

However, the restriction of trailing closure syntax to only the last closure has limited its applicability. Implementation of SE-0279 allows additional labeled closures to follow the initial unlabelled closure.

但是,将尾随闭包语法限制为仅最后一个闭包限制了其适用性。 SE-0279的实施允许其他带标签的封闭物跟随最初的未标记的封闭物。

Two key points to keep in mind:

请记住两个要点:

  • The first trailing closure drops its argument label.

    尾随的第一个闭包将删除其参数标签。
  • Subsequent trailing closures require argument labels.

    随后的结尾闭包需要参数标签。

Before Swift 5.3 — Single trailing closure

Swift 5.3之前的版本-单尾封闭

UIView.animate(withDuration: 0.5, animations: {self.view.alpha = 0.5
}) { _ in
self
.view.backgroundColor = UIColor.red
}

Swift 5.3 — Multiple trailing closure

Swift 5.3-多个尾随闭包

UIView.animate(withDuration: 0.5) {self.view.alpha = 0.5
} completion: { _ in
self
.view.backgroundColor = UIColor.red
}
Image for post

Well, so much efforts, just to remove a few braces 🤔. No wonder inclusion of this feature is highly debatable 🧐

好吧,那么多的努力,只是为了去除一些牙套 ces 难怪此功能值得商 highly

枚举类型的综合可比一致性 (Synthesized Comparable Conformance for enum types)

With Swift 4.1, the compiler had a way to automatically synthesize conformance to Equatable and Hashable. This led to a reduction of boilerplate code in the scenarios wherever correct implementation is possible.

使用Swift 4.1,编译器可以自动合成对EquatableHashable 。 这导致在可能正确实施的情况下减少了样板代码。

Their sibling Comparable was left out at that time due to the fact that it was complex to get the comparison order. Well, not anymore 😄. With SE-0266, Swift 5.3 brings opt-in synthesized Comparable conformances for enum types without raw or associated values. Example from the GitHub page,

当时他们的兄弟Comparable由于比较顺序比较复杂而被排除在外。 好吧,不再是😄。 使用SE-0266时 ,Swift 5.3为没有原始值或关联值的enum类型带来了选择加入的综合Comparable一致性。 GitHub页面上的示例,

enum Membership: Comparable {case premium(Int)case preferredcase general
}let array: [Membership] = [.premium(1), .preferred, .premium(0), .general]let sortedArray = array.sorted()
//[.premium(0), .premium(1), .preferred, .general]

The older version would give an error like this Type ‘Membership’ does not conform to protocol ‘Comparable’ but in Swift 5.3, it works like a charm 🌟

较旧的版本会出现这样的错误,例如“成员资格”类型不符合协议“可比较”,但是在Swift 5.3中,它就像一个魅力

We can, of course, have our own implementation like before if needed.

当然,如果需要,我们可以像以前一样拥有自己的实现。

列举案例作为协议证人 (Enum Cases as Protocol Witnesses)

Enums have always made our lives easier if you know how to use them 😉wisely. Swift 5.3 adds more to its sweetness.

枚举始终使我们的生活更加轻松,如果您知道如何明智地使用它们。 Swift 5.3为其甜美度增加了更多。

This implementation in SE-0280 aims to lift an existing restriction that the enum cases cannot participate in protocol witness matching. The Github readme has an awesome must-look example to understand this.

SE-0280中的此实现旨在解除枚举案例无法参与协议见证匹配的现有限制。 Github自述文件有一个很棒的必须看的例子来理解这一点。

Now, the compiler allows a static protocol requirement to be witnessed by an enum case, under the following rules:

现在,编译器允许在下列规则下以枚举实例见证静态协议要求

A static, get-only protocol requirement having an enum type or Self type can be witnessed by an enum case with no associated values.

具有枚举类型或Self类型的静态,仅获取协议要求可以由没有关联值的枚举案例来见证。

A static function requirement with arguments and returning an enum type or Self type can be witnessed by an enum case with associated values having the same argument list as the function's.

具有参数并返回枚举类型或Self类型的静态函数需求可以通过枚举实例来见证,该枚举实例具有与该函数的参数列表相同的关联值。

基于类型的程序入口点 (Type-Based Program Entry Points)

With the implementation of SE-0281, users can now use the @main attribute on a single type instead of writing top-level code.

通过SE-0281的实现,用户现在可以在单个类型上使用@main属性,而不用编写顶级代码。

The Swift compiler will recognize a type annotated with the @main attribute for providing the entry point for a program. Types marked with @main have a single implicit requirement: declaring a static main() method. This main() method will typically be provided by libraries or frameworks so that the author of a Swift program will only need to use the @main attribute to indicate the correct starting point.

Swift编译器将识别一个带有@main属性注释的类型,以提供程序的入口点。 标有@main类型有一个隐式要求:声明一个静态main()方法。 这个main()方法通常由库或框架提供,因此Swift程序的作者仅需要使用@main属性来指示正确的起点。

// In a framework:
public protocol ApplicationRoot {
// ...
}
extension ApplicationRoot {
public static func main() {
// ...
}
}
// In MyProgram.swift:
@main
struct MyProgram: ApplicationRoot {
// ...
}

多模式捕获条款 (Multi-Pattern Catch Clauses)

Currently, each catch clause in a do-catch statement can only contain at-most single pattern and where clause.

当前, do-catch语句中的每个catch子句最多只能包含单个模式和where子句。

Image for post

Because of the above restrictions, a developer ends up either nesting the switch inside a catch clause, defeating the purpose of supporting pattern matching in catch clauses, or ends up splitting the code into multiple catch clauses, thus duplicating the body, which is undesirable. With SE-0276, Swift 5.3 adds another capability of having multiple catch cases at once 🎉.

由于上述限制,开发人员最终要么将开关嵌套在catch子句中,就无法达到在catch子句中支持模式匹配的目的,要么最终将代码拆分成多个catch子句,从而使主体重复,这是不希望的。 借助SE-0276 ,Swift 5.3增加了另一个功能,可以一次拥有多个抓包。

do {
// do something
} catch TaskError.someRecoverableError { // OK
recover()
} catch TaskError.someFailure(let msg),
TaskError.anotherFailure(let msg) { // Also Allowed
showMessage(msg)
}

Float16- SE-0277 (Float16 — SE-0277)

The last decade has seen a dramatic increase in the use of floating-point types smaller than Float(32-bit).

在过去的十年中,使用小于Float (32位)的浮点类型的使用急剧增加。

As stated in the proposal, the addition of this type can be used widely in various use-cases on mobile GPUs for computation, as a pixel format for HDR images, and in ML applications for compressed format for weights.

如提案中所述,这种类型的添加可广泛用于移动GPU的各种使用情况中进行计算,作为HDR图像的像素格式以及在ML应用中用于权重的压缩格式。

Thus adding Float16 seems right ✅. With the advancements happening, we can expect some more Math functions coming soon 😃

因此添加Float16似乎正确right。 随着进步的发展,我们可以期待更多的数学函数即将推出😃

内隐的“自我” (Implicit “self”)

Tired of writing self in escaping closure blocks? SE-0269 brings a surprise of implicit self to you. This can help your laziness to persist 😆. It is quite useful in situations where the developer has already made their intent explicit, or where strong reference cycles are otherwise unlikely to occur. It might be a bit dangerous for devs who rely on the Poka-Yoke mechanism to safeguard the retain-cycles🧐.

厌倦了在逃逸的封闭块中写自我SE-0269给您带来内在自我的惊喜。 这可以帮助您保持懒惰。 在开发人员已经明确表达其意图的情况下,或者在其他情况下不太可能发生强大的参考周期的情况下,这非常有用 对于依靠Poka-Yoke机制保护保留周期的开发人员来说,这可能有些危险。

Image for post

完善didSet语义 (Refine didSet Semantics)

With the current implementation of didSet observer, the getter of property gets called to fetch the oldValue whether we use it or not in the body of the observer. What's wrong with that…💁🏻‍♀️But if we look closely, it is doing some redundant work by allocating storage and loading a value that isn’t used. And that…could also be really expensive 🤓.

使用didSet观察器的当前实现,无论我们是否在观察器的主体中使用它,都将调用属性的getter来获取oldValue 。 但是,如果我们仔细观察,它会通过分配存储空间并加载未使用的值来做一些多余的工作。 那……也可能真的很贵🤓。

Image for post

SE-0268 brings down this redundancy and uses a lazy approach. So the property’s getter is no longer called if we do not refer to the oldValue within the body of the didSet 🥳.

SE-0268降低了这种冗余并使用了惰性方法。 因此,如果我们未在didSet主体中引用oldValue ,则不再调用该属性的getter。

非连续元素的收集操作😯 (Collection Operations on Non-Contiguous Elements 😯)

Range<Index> is used to perform various operations on collections with consecutive positions. But what if we can use it with discontiguous positions in an arbitrary collection?

Range<Index>用于对具有连续位置的集合执行各种操作。 但是,如果我们可以在任意集合中的不连续位置使用它呢?

SE-0270 adds a RangeSet type to represent multiple, noncontiguous ranges, as well as a variety of collection operations for creating and working with range sets.

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]

上下文通用声明中的“ where”子句 (“where” clauses on contextually generic declarations)

SE-0267 lifts the restriction on attaching where clauses to member declarations that can reference only outer generic parameters.

SE-0267取消了将where子句附加到只能引用外部通用参数的成员声明的限制。

This improvement only covers member declarations that already support a generic parameter list i.e. properties and unsupported constraints on protocol requirements are out of scope.

此改进仅涵盖已经支持通用参数列表的成员声明,​​即属性和对协议要求的不受支持的约束不在范围内。

protocol P {
// error: Instance method requirement 'foo(arg:)' cannot add constraint 'Self: Equatable' on 'Self'
func foo() where Self: Equatable
}
class C {
// error: type 'Self' in conformance requirement does not refer to a generic parameter or associated type
func foo() where Self: Equatable
}

Whereas placing where clause on an extension member rather than the extension itself becomes possible:

而将where子句放在扩展成员而不是扩展本身上成为可能:

extension P {
func bar() where Self: Equatable { ... }
}

字符串初始化程序添加了对未初始化存储的访问权限 (String Initializer added with Access to Uninitialized Storage)

There are situations where we need a temporary buffer to be allocated and copied into. For example, bridging NSString to String, which currently uses standard library internals to get good performance when using CFStringGetBytes.

在某些情况下,我们需要分配一个临时缓冲区并将其复制到其中。 例如,将NSString桥接到String ,当使用CFStringGetBytes时,当前使用标准库内部函数来获得良好的性能。

SE-0263 adds a new initializer unsafeUninitializedCapacity. As explained in ReadMe “It takes a closure that operates on an UnsafeMutableBufferPointer referencing the uninitialized contents of the newly created String's storage and returns a count of initialized elements or 0.”

SE-0263添加了新的初始化程序unsafeUninitializedCapacity 。 如自述文件中所述: “它需要一个在 UnsafeMutableBufferPointer 上进行操作的闭包,该闭包 引用了新创建的String存储的未初始化内容,并返回一个初始化元素或0的计数。”

This helps in reducing the overhead of heap allocation that is needed for this temporary usage.

这有助于减少此临时用法所需的堆分配开销。

Wondering what are unsafe pointers. Here is an amazing article to know everything about unsafe pointers in swift.

想知道什么是不安全的指针。 这是一篇了不起的文章,可以Swift了解有关不安全指针的所有信息。

还有什么 (What else)

Can’t wait to get your hands dirty with Swift 5.3? Go ahead with these snapshots provided by swift.org to experiment with new features and contribute to the open-source.

等不及要使用Swift 5.3弄脏双手了? 继续使用swift.org提供的快照 ,以尝试新功能并为开源做出贡献。

Image for post
To Windows or Linux developers 致Windows或Linux开发人员

翻译自: https://medium.com/swlh/swift-5-3-sailing-towards-performance-and-quality-b254b74778ab

swift3到swift5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值