この記事の要点
- Swift 5.1 が正式リリースされました。Swift 5 の強みを土台に、module stability を導入して安定した言語機能をコンパイル時にまで広げ、将来の Swift リリースでも動作するバイナリフレームワークを作成・共有できるようにしたリリースです。
- 言語・標準ライブラリには、property wrapper、opaque result type、key path member lookup、適切なコレクション型に対する差分(diffing)、
String向けの新 API といった機能が加わりました。これらにより、より良い API を設計しやすくなり、よくあるボイラープレートを減らせます。 - Swift 5.1 は Swift 5 とソース互換で、Swift 4.2 および Swift 4 / 4.1 の互換モードもサポートします。Apple プラットフォーム向けには Xcode 11 に同梱され、Linux(Ubuntu 14.04 / 16.04 / 18.04)向けの公式バイナリも提供されます。
主な変更点
module stability
Swift 5.1 では、module stability のサポートにより、他者と共有できるバイナリフレームワークを作成できるようになりました。module stability は、バイナリフレームワークの API を記述するテキストベースの module interface ファイル(.swiftinterface)を新たに定義します。これにより、異なるバージョンのコンパイラを使うコードからでもフレームワークをコンパイルして利用できます。
このリリースには library evolution をサポートする機能も含まれます。詳細は SE-0260(Library Evolution) を参照してください。
ABI 安定化・module stability・library evolution の背景については、次の解説記事も参照してください。
標準ライブラリの更新
標準ライブラリには次の新機能が加わりました。
-
コレクションの差分(diffing)(SE-0240): 適切な型のコレクション同士の差分を計算し、その差分を適用できるようになりました。
let diff = newArray.difference(from: oldArray) let updated = oldArray.applying(diff) - 配列初期化の柔軟化(SE-0245): 未初期化のストレージにアクセスして
Arrayを初期化できるイニシャライザが追加され、要素を一度に書き込む処理を効率よく書けます。 String周りの API 追加(SE-0247 / SE-0248): 連続メモリ上の文字列(contiguous string)の作成・取り扱い、Unicode テキストを扱うためのヘルパー、String.IndexやRangeのジェネリックなイニシャライザなどが加わりました。- SIMD 型の API 改善(SE-0251): ベクトルの拡張、reduction、vector swizzle のサポートなど、SIMD 型を扱うための段階的な API 改善が入りました。
-
Identifiableプロトコル(SE-0261): 一意な識別子を必要とするエンティティをサポートするプロトコルが導入されました。struct User: Identifiable { let id: UUID var name: String }
言語・コンパイラの更新
Swift 5.1 では次の言語機能が加わりました。
-
property wrapper(SE-0258): プロパティの値に対するアクセスパターンを定義するための、一貫した汎用の構文が導入されました。遅延初期化やアトミック操作、スレッド固有のストレージ、copy-on-write の挙動などを、繰り返しの実装なしに切り出して再利用できます。
@propertyWrapper struct Clamped { private var value: Int private let range: ClosedRange<Int> init(wrappedValue: Int, _ range: ClosedRange<Int>) { self.range = range self.value = min(max(wrappedValue, range.lowerBound), range.upperBound) } var wrappedValue: Int { get { value } set { value = min(max(newValue, range.lowerBound), range.upperBound) } } } struct Color { @Clamped(0...255) var red: Int = 0 @Clamped(0...255) var green: Int = 0 @Clamped(0...255) var blue: Int = 0 } -
opaque result type(SE-0244): 同じプロトコルに適合する異なる型を
someでまとめて返したり、API の実装の詳細を隠したりできます。func makeShape() -> some Shape { return Rectangle() } - key path member lookup(SE-0252):
@dynamicMemberLookupで、文字列ではなく key path を使ったメンバーアクセスを定義できるようになり、型安全な動的メンバーアクセスを実現できます。 -
単一式の関数・getter での
returnの省略(SE-0255): 本体が 1 つの式だけの関数や getter ではreturnを書かなくてよくなりました。func double(_ x: Int) -> Int { x * 2 } Selfの利用範囲の拡大(SE-0068): クラスや値型でもSelfを使えるようになりました。-
memberwise initializer のデフォルト値の合成(SE-0242): デフォルト初期化子を持つプロパティについて、コンパイラが合成する memberwise initializer にもデフォルト値が与えられ、その引数を省略できるようになりました。
struct Point { var x = 0 var y = 0 } let p = Point(x: 10) // y は 0 - static / class subscript(SE-0254): 型自体に対する
subscriptを定義できるようになりました。
SwiftSyntax と開発ツール
- SwiftSyntax が、Swift コンパイラのパーサを直接使う形に再設計され、性能が大きく改善されました。構文木の走査などの内部データ構造も効率化されています。
- macOS / Ubuntu 向けの Swift 5.1 OSS ツールチェインには、Swift および C 系言語向けの Language Server Protocol 実装である SourceKit-LSP のバイナリが含まれます。
移行とドキュメント
Swift 5.1 は Swift 5 とソース互換で、Swift 4.2 および Swift 4 / 4.1 の互換モードもサポートします。Xcode 11 には多くのソース変更を自動処理できるコードマイグレータが含まれ、機械的でない変更を案内する移行ガイドも用意されています。Swift 5.1 に対応した『The Swift Programming Language』の更新版も Swift.org で公開され、Apple Books でも無料で入手できます。
Swift 利用者への影響
- バイナリフレームワークを安心して配布・利用できます。 module stability により、異なるコンパイラバージョンとの組み合わせでも動作するバイナリフレームワークを作成・共有できるようになりました。
- API 設計の幅が広がります。 property wrapper でプロパティのアクセスパターンを再利用可能な形に切り出せ、opaque result type で具体型を隠したまま統一的な戻り値を返せます。いずれも SwiftUI などの宣言的 API の基盤にもなっています。
- ボイラープレートが減ります。 単一式での
return省略、memberwise initializer のデフォルト値合成、key path member lookup などにより、繰り返し書いていたコードを減らせます。 - 移行のハードルは低めです。 Swift 5.1 は Swift 5 とソース互換で、Xcode のコードマイグレータと移行ガイドが移行を支援します。
関連リンク
- このリリースの計画と管理方針については Swift 5.1 のリリースプロセス を参照してください。
swift-5.1-branchは、次のリリースに向けた変更を蓄積するため引き続き開かれた状態に保たれました。 - 前のメジャーリリースについては Swift 5 リリース を参照してください。
- 本記事に関連する解説記事: ABI 安定性とその先へ / ABI 安定性以後の Apple プラットフォームでの Swift の進化
- 本記事で触れた主な Proposal ダイジェスト:
- Swift のダウンロード