Swiftの最新のメジャーリリースには、言語とライブラリに多数の変更とアップデートが含まれている。特に注目すべきは新しい String 機能、拡張されたコレクション、アーカイブとシリアライゼーションなどだ。

Swift 4の文字列は Collection プロトコルに準拠しているため、直接イテレーションが可能であるだけでなく、次の例のように、コレクションやシーケンスで使用するすべての機能が提供されている。

for c in myString { print(c) } myString.filter { c in return boolCheck(c) } let l = myString.count let myString2 = myString.dropFirst()

さらに、文字列のスライスが Substring 型のインスタンスになったことで、 StringProtocol に対応すると同時に、 String 型と同等に使用できるようになった。この変更は、 Substring が文字列スライスをコピーしなくなることによって、スライス処理のパフォーマンスの向上にも寄与する。 Substring が String に変換されてAPIで使用されるまで、コピー処理を遅延させることが可能になるのだ。

その他の新しい文字列機能としては、Unicode 9と複数行リテラルのサポートがある。

Swift 4では、 Dictionary や Set など、コレクション型の生成、使用、管理の方法も改善されている。

まず最初に、タプルのシーケンスからのDictionaryの生成と、Dictionaryの生成あるいは２つのDictionaryのマージ時に重複のあった場合の処理方法を指定することが可能になった。

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 }

Dictionary と Set を Array 以外に、同じ型の別オブジェクトにもフィルタリングできるようになった。さらにDictionaryでは、 mapValues メソッドもサポートされている。

let catalog4 = catalog.filter { $0.value < 15.0 } let catalog5 = catalog.mapValues { $0 * 1.2 }

Dictionaryに追加されたもうひとつの便利な機能は、要素をアクセスする時のデフォルト値を指定できるようになったことだ。これを使って、添字演算子で非opt型を返すことが可能になる。

let price1 : Float = catalog['none', default: 0.0] let price2 : Float? = catalog['none']

Swift 4では、すべての Collection 型がジェネリックな添字をサポートする。これはつまり、次のような JSON 構造体を定義して、インデックスされた結果をDictionaryにキャストしないことが可能である、ということだ。

struct JSON { init(dictionary: [String:Any]) { ... } subscript<T>(key: String) -> T? { ... } } let json = ... let result: String? = json['item']

もうひとつの歓迎される言語拡張は、アーカイブとシリアライゼーションのサポートだ。これまでは NSObject と NSCoding で扱う必要があった上に、 struct や enum 型では使用できなかった。その代わりにSwift 4では、 Codable プロトコル通じて、すべての型のシリアライゼーションが加えられている。Ole Begemann氏が、Swift 4でのコーディングとデコーディングに関して、素晴らしいイントロダクションを提供してくれている。例えば下記は、 Codable 型の定義方法を示している。

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)]

最後の注意点として、Swift 4には２つの言語モードがあり、 -swift-version コンパイルオプションで選択するようになっている。Swift 3.2モードでは、Swift 3.xコンパイラに対応するソースの大半が受け入れられる。このモードでもSwift 4言語機能は利用可能だが、既存APIのアップデート部分は利用できない。Swift 4.0モードでは、ある程度のソース変更を行なうことで、Swift 4の全機能にアクセスできる。必要となる変更は、通常はXcodeのマイグレーションアシスタントを使って処理可能だ。

Swift 4には他にもいろいろある。SwiftのメンテナであるTed Kremenek氏の発表と、Ole Begemann氏によるインタラクティブなPlaygroundでの新機能すべてのデモを見逃してはならない。

Swift 4はXcode 9に同梱されている他、Xcode 8.3に手動でインストールすることもできる。