この記事の要点
- Swift 5.4 が正式リリースされました。言語機能の追加、ランタイム性能とコードサイズの改善、そして開発体験(ビルド・コード補完・型チェック・デバッグ)の改善を中心としたリリースです。
- 言語面では、複数の可変長引数、implicit member 構文の拡張、result builder、ローカル関数のオーバーロード、ローカル変数への property wrapper が加わりました。あわせて、将来の並行処理モデルに向けて
awaitを識別子として使うコードに警告が出るようになりました。 - ランタイムでは、プロトコル適合チェックの高速化や、連続した配列変更での冗長な一意性チェックの除去などにより、実行時性能とコードサイズが改善されました。
- 開発体験では、インクリメンタルビルドでの再コンパイル対象の削減、大きな関数本体でのコード補完の高速化、「リンクした」式の型チェック性能の改善、result builder の診断改善などが入りました。
- Swift Package Manager は Windows サポート、
@mainを使える実行可能ターゲットの宣言、全プラットフォームでのテスト自動探索などに対応し、Windows プラットフォームのサポートも前進しました。
主な変更点
言語の更新
Swift 5.4 では、Swift Evolution プロセスを経た次の言語機能が実装されました。
-
複数の可変長引数(SE-0284): これまで関数・subscript・イニシャライザに 1 つしか書けなかった可変長引数(
Int...のような引数)を、複数宣言できるようになりました。func forecast(highs: Int..., lows: Int...) { ... } forecast(highs: 30, 28, 27, lows: 18, 16, 15) -
implicit member 構文の拡張(SE-0287): 型を推論できる文脈で先頭の型名を省略できる「
.foo」という書き方(implicit member 構文)が、メソッド呼び出しやプロパティアクセスを連鎖させた式にも使えるようになりました。// 従来は UIColor を明示する必要があった let color: UIColor = .red.withAlphaComponent(0.5) -
result builder(SE-0289): 一連の宣言的なコンポーネントから、結果となる値を組み立てる仕組みを提供する
@resultBuilderが正式に言語機能となりました。SwiftUI のViewBuilderのような DSL をライブラリ側で定義できます。 -
ローカル関数のオーバーロード: 関数内で定義したローカル関数を、同名で引数が異なる形でオーバーロードできるようになりました。
-
ローカル変数への property wrapper: これまで property wrapper を適用できるのは型のプロパティだけでしたが、関数内のローカル変数にも適用できるようになりました。
加えて、将来の並行処理モデル(async/await)の導入に備えて、await を識別子として(変数名や関数名として)修飾なしで使っているコードに、コンパイラが警告と Fix-It を出すようになりました。これらの識別子は将来の Swift で SE-0296 のキーワード await として解釈されるようになります。
ランタイム性能とコードサイズの改善
- プロトコル適合チェックの高速化: ランタイムでのプロトコル適合チェックが、過去の検索結果をキャッシュするハッシュテーブル実装の高速化により大きく速くなりました。これにより、よく使われる
as?/as!によるキャストも速くなります。 -
冗長な一意性チェックの除去: 連続した配列の変更で、copy-on-write のための一意性チェックが繰り返し行われていたのを、不要な分を省くようになりました。
func foo(_ a: inout [Int]) { // ここでは copy-on-write (CoW) チェックが必要 a[0] = 1 // コンパイラは、ここでは // 冗長な CoW チェックを生成しなくなった a[1] = 2 } - このほか、
String補間のより積極的な定数畳み込み、inout引数やループ内での retain/release 呼び出しの削減、標準ライブラリのジェネリックメタデータのコンパイル時特殊化(dirty メモリ使用量の削減と性能向上)などの改善が入っています。
Swift Package Manager の更新
- 実行可能ターゲットの明示的な宣言(SE-0294): ツールバージョン 5.4 のパッケージで、ターゲットを実行可能(executable)として明示的に宣言できるようになり、パッケージのコードで
@mainキーワードを使えるようになりました。 - Windows サポート: Swift Package Manager が Windows でも動作するようになりました。
- 依存のキャッシュ: パッケージ依存をユーザー単位でキャッシュし、同じパッケージを再利用する際のネットワーク量を減らし、依存解決を高速化します。
- テストの自動探索: 全プラットフォームでテストの自動探索がデフォルトになり、
LinuxMain.swiftが不要になりました(同ファイルは deprecated)。 - このほか、マニフェスト読み込み・キャッシュを含む依存解決インフラの改善や、より具体的で対処しやすいエラーメッセージへの診断改善が入っています。
Windows プラットフォームのサポート
- Swift Package Manager が Windows で動作するようになりました。
WinSDKモジュールが拡張され、Windows 開発者 SDK のより広い範囲をカバーするようになりました。C インターフェイスを Swift へブリッジするライブラリを手作業で用意しなくても、より多くの API を Windows アプリで使えます。- インストーラの改善により、デフォルトで必要なフラグが減り、外部ツールとツールチェインを組み合わせて使いやすくなりました。
開発体験の改善
- ビルド性能: コンパイラがファイル間の依存をより正確に追跡できるようになり、多くの変更でインクリメンタルビルド時に再コンパイルされるファイル数が大きく減りました。
struct/enum/ クラス / プロトコルのメンバー変数・関数への依存が個別に追跡されるようになり、これらの変更後の再ビルドが速く・小さくなります。インクリメンタルビルドの成果物の決定性も多くのケースで向上しました。 - コード補完: 大きな関数本体内でのコード補完が大幅に高速化しました(ある例では
self.の補完が Swift 5.3 比で 4 倍速く、20ms から 5ms に)。エラーを含む式や、追加の文脈なしには曖昧な式でも、補完がより確実に機能するようになりました。 - 型チェッカ:
a + b + (2 * c)のように演算子で「リンクした」式の型チェック性能が改善され、従来タイムアウトしていたコードが 100ms 未満で完了するようになりました。また、リテラル式を含むネストした配列リテラルの型チェック性能も向上し、従来「too complex to solve in reasonable time」となっていた不正なコードに対して、原因を正確に示すエラーを出せるようになりました。 - result builder の診断: result builder 内の不正な文(不正な
return文など)、不正な宣言の参照、パターンマッチのエラーに対する診断が改善されました。たとえば result builder の本文で明示的なreturnを使うコードには、returnを削除する Fix-It 付きのエラーが出ます。 - デバッグ: Apple プラットフォームで、resilient な型(
URL・URLComponents・Notification・IndexPath・Decimal・Data・Date・Measurement・UUIDなどの Foundation の値型を含む)の変数が、Xcode の変数ビューやframe variable/vコマンドで再び表示されるようになりました。
Swift 利用者への影響
- API 設計の表現力が上がります。 result builder により SwiftUI のような宣言的 DSL をライブラリ側で定義でき、implicit member 構文の拡張で
.red.withAlphaComponent(0.5)のような連鎖も型名を省略して書けます。複数の可変長引数も使えます。 - 実行時性能とアプリサイズが改善します。 プロトコル適合チェックやキャストの高速化、冗長な copy-on-write チェックの除去、メタデータのコンパイル時特殊化などにより、実行時オーバーヘッドとコードサイズが下がります。
- ビルドとエディタが速くなります。 インクリメンタルビルドの再コンパイル対象が減り、大きな関数でのコード補完が高速化し、複雑な式の型チェックがタイムアウトしにくくなりました。
- パッケージで実行可能ターゲットを宣言できます。 SwiftPM で executable ターゲットを明示でき、パッケージのコードで
@mainを使えます。テスト自動探索が全プラットフォームでデフォルトになり、LinuxMain.swiftが不要になりました。 - Windows での開発が前進します。 SwiftPM が Windows で動作し、
WinSDKの拡張により Windows アプリでより多くの API を使えるようになりました。 - 将来の並行処理に備えられます。
awaitを識別子として使っているコードに警告が出るため、async/await導入前に名前を見直せます。
関連リンク
- 前のリリースについては Swift 5.3 リリース を参照してください。
- Windows での Swift については Windows で動く Swift の登場 を参照してください。
- 本記事で触れた Proposal ダイジェスト:
- Swift のダウンロード
- Swift Package Manager