伴随春天而来的 Swift 3.1

1,174 阅读3分钟

最近发布的 Swift 3.1,咱们一起探索下它都有什么改动。

Sequence 协议添加两个方法

protocol Sequence {
  // ...
  /// Returns a subsequence by skipping elements while `predicate` returns
  /// `true` and returning the remainder.
  func drop(while predicate: (Self.Iterator.Element) throws -> Bool) rethrows -> Self.SubSequence
  /// Returns a subsequence containing the initial elements until `predicate`
  /// returns `false` and skipping the remainder.
  func prefix(while predicate: (Self.Iterator.Element) throws -> Bool) rethrows -> Self.SubSequence
}

drop 方法会遍历所有元素并接受一个 predicate 对于 predicate 返回 true 的所有元素,生成一个新的数组并返回。

prefix 方法也比较实用, 它接受一个 predicate,直到 predicate 返回 false,并忽略之后所有的元素后生成一个新的集合并返回。 正好是 prefix 的含义。

这个改动来自 SE-0045 号提案,原地址:github.com/apple/swift…

Swift 版本编译兼容性语法支持

因为 Swift 版本变化非常快,并且标准库的接口也经常会有很大变化,所以这次 Swift 对 @available 语法添加了扩展,现在你可以指定代码的语言版本了, 比如:

@available(swift, obsoleted: 3.1)
class Foo {
  //...
}

上面这段代码的意思是,只有在 Swift 3.1 以下的编译器,这个类才有效,以后的版本无效。 obsoleted 就是从这个版本中移除的意思。个人感觉这个特性还是非常有用的,尤其是经历过 Swift 版本更新后项目被搞挂的同学了。

这个改进源自提案 SE-0141: github.com/apple/swift…

这里面也说了,尽管以前也可以用 #if swift(>= N) 这样的语法来判断 Swift 版本,但这个毕竟是编译预处理命令,以为这你要针对每个 Swift 版本的编译器都构建一个版本。(可以想想编译预处理的原理,就不难理解为什么要针对每个版本都构建了。)

精确的数值转换

Swift 3.1 对数字类型的转换提供了一个精确化的实现,比如:

let num = Int(exactly: 2.2)
print(num)  // 输出 nil

上面这个代码输出结果是 nil, 而不是 2。

为什么要提供 exactly 这种实现呢,我的解读是这样。因为传给 Int 构造方法的是 2.2 的浮点数, 如果把它转换成 Int 类型就会变成 2。在某些情况下有可能这不是你期望的结果,比如咱们平常都会解析从服务端发送过来的 JSON 数据。

这个接口如果发现从浮点数转换成整型数会损失精度, 就会直接返回 nil。 同样,下面这个代码就会正常转换,因为这次转换没有损失精度:

let num = Int(exactly: 2.0)
print(num)  // 输出 2

这个改动来自提案 SE-0080:github.com/apple/swift…

结束

以上就是 Swift 3.1 的几个主要改动了,这次发布的是一个小版本,所以不会对语言有太多天翻地覆的变化。 除了对语言本身的改进,还有对包管理工具的改进。

完整的内容,可以参考官方的发布文档: swift.org/blog/swift-…

如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~

本站文章均为原创内容,如需转载请注明出处,谢谢。