この記事の要点
- Swift 5.7 が正式リリースされました。言語と標準ライブラリの大きな追加、開発体験の向上、エコシステム(SourceKit-LSP や Swift Package Manager)の改善、Windows サポートの洗練などが含まれます。
- 言語面では、
if letの省略記法や複数文クロージャの型推論といったボイラープレートの削減、ジェネリックプログラミングの制約緩和(primary associated type、existential の拡張、暗黙的な existential の open など)、新しい文字列処理(Regex)が中心です。 - 並行処理では、
Sendableと@Sendableクロージャ、Clock/Instant/Duration、そして分散環境向けのアクター(distributed actor)が加わりました。 - ポインタ API の使い勝手も改善され、ジェネリクスの型チェッカは一から再実装されて正確性と性能が向上しました。
主な変更点
言語と標準ライブラリ
if let の省略記法(SE-0345)
既存のオプショナル変数を同じ名前でアンラップする際、if let foo = foo のように名前を繰り返す必要がありました。Swift 5.7 では右辺を省略して書けます。
if let foo {
// foo はアンラップ済み
}
文字列処理(Regex)
Swift 5.7 では、正規表現を中心とした新しい文字列処理機能が言語・標準ライブラリの両面から追加されました。型としての Regex(SE-0350)、宣言的に正規表現を組み立てる Regex builder DSL(SE-0351)、正規表現リテラル(SE-0354)、正規表現を活用した文字列処理アルゴリズム(SE-0357)などです。
let regex = /(\d+)-(\d+)/
if let match = "12-34".firstMatch(of: regex) {
print(match.1, match.2) // 12 34
}
ジェネリックプログラミングの制約緩和
長年の制約が解消され、ジェネリックなコードがより自然に書けるようになりました。
- 全プロトコルでの existential の解禁(SE-0309):
associatedtypeを持つプロトコルなどでも existential 型(any P)を使えるようになりました。 - primary associated type の軽量な制約構文(SE-0346):
Collection<Int>のように、associated type を山括弧で指定して制約できます。 - 暗黙的に open される existential(SE-0352): existential の値をジェネリック関数に渡すと、その実体型が暗黙的に open され、より多くの場面で existential を扱えます。
- 制約付き existential 型(SE-0353):
any Collection<Int>のように、existential にも primary associated type の制約を付けられます。
並行処理
Sendableと@Sendableクロージャ(SE-0302): 並行に共有しても安全な型を表すSendableプロトコルと、@Sendableクロージャが導入され、データ競合安全性の基盤が整いました。Clock/Instant/Duration(SE-0329): 時間と時刻を扱う統一的な API が標準ライブラリに加わり、Task.sleepなどで利用できます。- 分散アクターの isolation(SE-0336): 分散環境向けに
distributed actorが導入され、ネットワークを越えたアクターの呼び出しを型安全に扱えます。これを基盤に、ピアツーピアのクラスタアクターシステムを提供する Swift Distributed Actors がオープンソース化されました。
開発体験
ジェネリクスの新実装
型チェッカのジェネリクス実装が一から書き直され、正確性と性能が向上しました。特に複雑な same-type 要件(コレクションの SubSequence への制約や、Self.Element == Self を要求する CaseIterable を使うコードなど)にまつわる長年のバグが多数修正されました。性能面でも、特定のプロトコル・associated type 構成で Swift 5.6 では指数的にかかっていた型チェック時間が、Swift 5.7 では線形になっています。
ARC の改善
Swift 5.7 では、最適化が許される場面で変数の寿命を短くする新しい規則が導入され、ARC の挙動がより予測しやすく、性能も向上しました。これにより、変数の寿命延長に依存する一般的なパターンの多くで withExtendedLifetime() を明示的に使わずに済むようになり、最適化ビルドの実行時にだけ現れる診断しづらい寿命バグから保護されます。
コード補完
関数呼び出しの引数・変数・グローバル関数のコード補完が型チェッカと密に統合され、曖昧なコードやエラーを含むコードでもより正確な候補を返すようになりました。
エコシステム
- SourceKit-LSP: Visual Studio Code 向けの Swift 拡張機能のリリースを支えるための改善が入りました。
Package.swiftなどの変更後にコンパイラ引数が再計算され、同一ワークスペース内の複数の SwiftPM プロジェクトを 1 つのサーバインスタンスで扱えるようになりました。 - Swift Package Manager: Package Registry Service(SE-0292)、disambiguation のためのモジュールエイリアス(SE-0339)が実装され、Swift 5.6 で導入された build tool plugin / command plugin が Xcode 経由でも使えるよう洗練されました。
- Windows サポート: ツールチェインが swift-driver を全面採用し、インストーラのサイズ縮小、SDK レイアウトの整理、マルチアーキテクチャ対応への準備、静的 Swift ライブラリの初期サポートなど、多くの洗練が加えられました。
Swift 利用者への影響
- 定型コードを減らせます。
if letの省略記法や複数文クロージャの型推論により、よくあるボイラープレートが減ります。 - 文字列処理が強力になります。
Regex型・正規表現リテラル・Regex builder により、正規表現を型安全に扱えるようになりました。 - ジェネリクスがより自然に書けます。 existential の解禁・暗黙的な open・primary associated type の制約構文により、これまで書けなかったジェネリックなコードが書けるようになりました。
- 並行処理の安全性が前進します。
Sendable/@Sendableの導入はデータ競合安全性の土台になり、Clock系 API や distributed actor も利用できます。 - 開発体験が向上します。 ジェネリクスの新実装による型チェックの高速化・正確化、より賢いコード補完、Visual Studio Code 拡張を支える SourceKit-LSP の改善などが効きます。
関連リンク
- 前のリリースについては Swift 5.6 リリース を参照してください。
- WWDC22 での言語アップデートのまとめは WWDC22 での Swift 言語アップデート を参照してください。
- 本記事で触れた Proposal ダイジェスト:
- Swift 5.7 に含まれる言語進化のProposal一覧: Swift Evolution dashboard
- Swift のダウンロード
- The Swift Programming Language