Swift 3 新特性

486 查看

 

前言

Swift 3今年晚些时候会与大家见面,它会带给Swift开发者巨大的代码层面的改变。
如果你最近没有跟进Swift Evolution的步伐,你也许会问到底有啥变化,它会怎样影响你的代码,以及你什么时候应该迁移到Swift 3上来。那么这篇文章会为你一一解答。
在这篇文章中,我会着重强调Swift 3中最重要的变化,因为这些会影响你的代码。我们一起来深掘吧!

开始

现在Swift 3预览版已经可以在Xcode 8 beta版使用了。尽管Swift 3的进化之路就要接近尾声,但是在接下来的几个月还是会做出一些变化。Swift 3的特性最终确定下来是在2016年,Xcode 8 正式版本发布的时候,所以你不得不推迟采用Swift 3编写的 App的发布日期。

为了让开发者能够按照他们自己的方式迁移到Swift 3上来,作为一个小的升级包,Xcode 8会包含Swift 2.3。从开发者的角度看,Swift 2.3跟Swift 2.2是一样的,只不过它会支持更多新的SDKs和WWDC上宣布的Xcode新特性。一旦Xcode 8 发布正式版,且你还没有迁移到Swift 3上来,那么你可以提交用Swift 2.3编写的App。

我建议你在playground中测试我们要讨论的特性,还有你也许可以在你的一个工程里运行迁移助手(还是不要拿公司项目做小白鼠了⚒),来感受一下新技术带来的变化。因为直到Xcode 8 正式版发布,Swift 3最终确定下来,你才能发布app,所以你该考虑等到所有事情有了定论再迁移到Swift 3上来。

迁移到Swift 3

当转换到Swift 3,你会发现几乎所有文件都需要改变!这主要是因为Cocoa API命名发生了改变。或者更准确的说,API相同的,但是现在OC,Swift的命名不统一。Swift 想要在接下来的时间让Swift的书写更加自然。

苹果在Xcode 8 中集成了迁移助手,它可以智能地帮助你修正这些变化。但是不要惊讶,如果你想要自行修改一下地方,那么迁移助手是不会自动帮你处理的。

你可以很快地转换到Swift 2.3 或者 Swift 3上来。如果你想转换回来,你可以在Xcode这么操作:Edit > Convert > To Current Swift Syntax … 。编译器像迁移助手一样智能,如果你在一个方法的调用上使用了旧的API,编译器会提供一个可选选项帮助你修正,这样你就能使用正确的现代的API了。

最重要的消息是:Swift 3目标是成为做出重大变化的最后一个版本。所以当Swift从一个版本迭代到另一个版本时,你能够保持自己的代码不变。尽管Swift 核心团队不能预测未来,但是他们承诺如果真的需要破坏源兼容性,他们会提供一个相当长的废弃周期。那就意味着Swift语言具有了源稳定性,这会促进更多保守公司采用Swift语言。

据说,二进制稳定性的目标还没有实现。在文章结尾,你会了解更多二进制稳定性的影响。

已经实现的—Swift进化提议

自从Swift开源,社区成员对于Swift的改变,给出了上百条提议。大多数提议(目前70条,或者更多)在讨论后都被接受了。那些被拒的提议也是在经过激烈的讨论后,做出的决定。无论如何,最终Swift核心团队会对所有的提议做出决定。

Swift核心团队与社区展开了广泛的互动交流。事实上,Swift在Github上获得了3万多颗星。日复一日,每周都有好几条提议被提出。甚至苹果的工程师想要做出改变时,也会在Github开出新的仓库,给出提议。

在以下部分,你会看到诸如[SE-0001]的标签。这些是是Swift Evolution 提议编号。这里的有编号的提议都是已被接受,会在Swift 3中实现。同时也会提供每一个提议的链接,你可以查看每一个改变的具体细节。

API 变化

Swift 3最大的更新是标准库采用了统一的命名规范。API 设计指南包含了团队构建Swift 3遵守的规范,这对于编写可读性,易维护性代码具有很重的价值。核心团队实践这样的准则:好的API设计总是考虑到调用场景。他们努力让API的用途变得更加清晰。废话不多说了,接下来是最有可能影响到你的变化。

第一个参数标签

我们以一个我们每天都在使用的实例开始。

11run_backwards_square-500x500

函数和方法中的第一个参数会需要一个便签,除非你有其他方面的需求。之前,当你调用一个函数或者方法时,你是省略第一个参数标签的[SE-0046]:

注意方法定义是怎么为外部名称使用诸如:”of”, “to”, “with”, 和 “in”等介词的。
如果方法调用没有介词,不需要标签的话,你可以显式地用下划线替换第一个参数名。

在很多编程语言中,方法会有一个基础的名字并提供不同的参数名。Swift也不例外,现在你会经常碰到重载方法,因为API更加直接。这里有一个例子,表现index()方法的两种形式:

总之,参数名的变化让方法名更加统一,也更加容易学习。

省略不必要的单词

在之前的苹果库的版本迭代中,方法会包括一个名字,用来指示返回值。得益于Swift编译器的类型检查,这显得不是很必须。团队认真审视后过滤掉了这些噪音只留下信号,结果很多重复的单词都被移除了。

12chatterbox

API在OC库转换到原生Swift方面更加智能 [SE-0005]:

现代化 GCD 和 Core Graphics

说到对旧的API的反对,GCD和Core Graphics成了最需要被改造的两个。

13swift-trimming-shears-square-500x500

GCD用在多线程任务中,例如:耗时的计算工作或者与服务器的通信。通过切换任务到不同的线程,可以避免阻塞用户线程。libdispatch库是用C语言写的,而且采用C语言风格的API。现在这些API被以原生Swift的风格重新设计。

相似的,Core Graphics 也是用C写的,过去使用了非常糟心的函数调用。可以看一下新方法的样子[SE-0044]:

枚举 Cases 首字母

另一个与你已经习惯的Swift编码方式不同是,枚举case 现在使用lowerCamelCase。这会让他们与其他属性更加一致 – [SE-0006]:

UpperCamelCase现在只在类型名和协议名上有保留。这可能要花上一段时间来适应,但是Swift团队这么做有他的理由—他们在努力达成一致性。

有返回值的函数和修改自身的函数

Swift标准库在用名词,动词的函数命名会越来越统一。你依据动作发生带来的影响来命名一个函数。经验法则是:如果它包含一个像”-ed” 或者”-ing”的后缀,那么认为这是一个名词函数。名词函数会返回一个值。如果它没有后缀,那么它很可能是一个必要的动词。这些”动词”函数在引用内存执行动作。这也被称为modifying in place。以下是遵守名词/动词规则的函数对。这里还有一些函数对[SE-0006]:

这里是一些行为上差异: