<p style="text-align: center;"><img alt="" src="https://simg.open-open.com/show/b87a09a250f3ad32dd9cf5bde817a116.jpg" /></p> <p>Swift最新的主要版本提供了针对语言本身以及标准库的大量改动和更新,最重要的变化包括新增的 <code>String</code> 功能、扩展集合、归档和序列化等。</p> <p>Swift 4中, <a href="/misc/goto?guid=4959011050214918571" rel="nofollow,noindex">String已全面遵循Collection协议</a> ,因此可直接迭代并提供了集合与序列类似的全部条件,例如:</p> <pre> for c in myString { print(c) } myString.filter { c in return boolCheck(c) } let l = myString.count let myString2 = myString.dropFirst()</pre> <p>此外String切片现已成为 <a href="/misc/goto?guid=4959011050340299503" rel="nofollow,noindex">下标(Substring)类型的实例</a> ,遵循 <code>StringProtocol</code> ,可按照与 <code>String</code> 类型完全一致的方式使用。这一改动有助于改善切片性能,因为 <code>Substring</code> 已经不再需要复制String切片。复制操作可延迟至 <code>Substring</code> 转换为 <code>String</code> 并被某些API使用的时候进行。</p> <p>String的其他功能还包括:支持Unicode 9以及 <a href="/misc/goto?guid=4959011050460361761" rel="nofollow,noindex">多行Literal</a> 。</p> <p>Swift 4还改进了用户创建、使用和管理集合类型的方式,例如 <a href="/misc/goto?guid=4959011050566342027" rel="nofollow,noindex">Dictionary和Set</a> 。</p> <p>首先,用户现在已经可以通过元祖(Tuple)序列创建字典,并指定如果遇到重复内容后的处理方式,而这一操作可在创建字典或合并两个字典的过程中进行:</p> <pre> let items = ["ItemA", "ItemB", "ItemC", "ItemA"] let prices = [14.40, 41.63, 3.71, 15.63] let catalog1 = Dictionary(uniqueKeysWithValues: zip(items, prices)) let catalog2 = Dictionary(prices, uniquingKeysWith: { (l, r) in l }) let catalog3 = Dictionary(prices, uniquingKeysWith: { (l, r) in l + r }) let merged = catalog.merge(catalog3) { (l, r) in r }</pre> <p><code>Dictionary</code> 和 <code>Set</code> 现在可以筛选成为原始类型的另一个对象,而不再筛选为 <code>Array</code> 。此外字典也已经可以支持新的 <code>mapValues</code> 方法:</p> <pre> let catalog4 = catalog.filter { $0.value < 15.0 } let catalog5 = catalog.mapValues { $0 * 1.2 }</pre> <p>关于字典还有一个实用的改进:在访问其元素时可以指定默认值,这样便可让下标运算符返回Non-opt类型:</p> <pre> let price1 : Float = catalog['none', default: 0.0] let price2 : Float? = catalog['none']</pre> <p>Swift 4中所有 <code>Collection</code> 类型均 <a href="/misc/goto?guid=4959011050667110591" rel="nofollow,noindex">支持泛型下标(Generic subscript)</a> 。这意味着我们可以定义下列 <code>JSON</code> 结构,不将索引的结果抛给字典:</p> <pre> struct JSON { init(dictionary: [String:Any]) { ... } subscript (key: String) -> T? { ... } } let json = ... let result: String? = json['item'] </pre> <p>对于该语言还有一个广受好评的改进:对归档和序列化的支持,以前这需要通过 <code>NSObject</code> 和 <code>NSCoding</code> 处理,无法用于 <code>struct</code> 和 <code>enum</code> 类型。但Swift 4通过 <code>Codable</code> 协议 <a href="/misc/goto?guid=4959011050764997017" rel="nofollow,noindex">增加了对所有类型的序列化支持</a> 。Ole Begemann对Swift 4的 <a href="/misc/goto?guid=4959011050849019498" rel="nofollow,noindex">编码和解码</a> 提供了入门简介。例如我们可以这样定义一个 <code>Codable</code> 类型:</p> <pre> struct Card: Codable, Equatable { enum Suit: String, Codable { case clubs, spades, hearts, diamonds } enum Rank: Int, Codable { case two = 2, three, four, five, six, seven, eight, nine, ten, jack, queen, king, ace } var suit: Suit var rank: Rank static func ==(lhs: Card, rhs: Card) -> Bool { return lhs.suit == rhs.suit && lhs.rank == rhs.rank } } let hand = [Card(suit: .clubs, rank: .ace), Card(suit: .hearts, rank: .queen)]</pre> <p>最后,Swift 4提供了两种语言模式,可通过 <code>-swift-version</code> 编译器选项进行选择。在Swift 3.2模式中,编译器可接受大部分使用Swift 3.x编译器编译的源代码。在该模式下,大部分Swift 4语言功能均可用,但针对之前已有API的各种更新均不可用。在Swift 4.0模式中,我们可以使用Swift 4的全部功能,但可能需要改动部分源代码,这一过程通常可通过Xcode的迁移助理实现。</p> <p>Swift 4还有很多改进,建议阅读Swift维护者Ted Kremenek的公告,并通过Ole Begemann在交互式Playground中提供的所有新功能演示来体验。</p> <p>Swift 4已包含在 <a href="/misc/goto?guid=4958330826810050427" rel="nofollow,noindex">Xcode 9</a> 中,并可手工安装到 <a href="/misc/goto?guid=4958991180449873431" rel="nofollow,noindex">Xcode 8.3</a> 中使用。</p> <p>阅读英文原文: <a href="/misc/goto?guid=4959011051012638058" rel="nofollow,noindex">Swift 4 is Officially Available: What's New</a></p> <p>来自: http://www.infoq.com/cn/news/2017/09/swift-4-official-release</p>