9月18日、AppleはSwift 6を正式にリリースした。このリリースにより、Swift言語はさらに多くのプラットフォームやドメインに対応可能となった。SwiftはApp Storeにある100万以上のアプリで使用されているが、その安全性、速度、使いやすさにより、ライブラリやインターネット規模のサービス、高性能でセキュアなコードにも適している。
メモリ安全性とデータ競合安全性
Swiftは従来からメモリ安全性を提供しており、変数が使用される前に初期化され、メモリが解放された後にアクセスされないようにする機能を備えている。Swift 6では、並行コードにおけるデータ競合を防止するための新しい言語モードが追加され、コンパイラエラーとしてデータ競合を検出することができるようになった。
以前のSwift 5.10では、このデータ競合安全性は警告として提供されていたが、Swift 6では、Sendable
の推論や、アクター間での可変状態の転送に関する新しいコンパイラ分析が追加され、誤検知が大幅に減少している。
またSwift 6では、新しい同期ライブラリが追加され、低レベルの並行性APIが提供されている。このライブラリには、アトミック操作や新しいミューテックスAPIが含まれている。
型付きthrows
Swift 6では、関数がスローするエラーの型をシグネチャの一部として指定できるようになった。この機能は、クライアントコードでスローされるエラーを汎用コードに渡したり、リソース制約のある環境でメモリを割り当てることができない場合に役立つ。
例:
func parseRecord(from string: String) throws(ParseError) -> Record {
// ...
}
このparseRecord(from:)
関数は、Record
インスタンスを返すか、ParseError
型のエラーをスローする。do..catch
ブロックでは、error
変数の型としてParseError
が推論される。
do {
let record = try parseRecord(from: myString)
} catch {
// 'error' has type 'ParseError'
}
非コピー型のサポートと所有権
Swift 6では、所有権モデルを強化し、リソース管理をより効率的に行えるようにするための非コピー型がサポートされている。具体的には、Swift 5.9で導入された~Copyable
構文により、ユニークな所有権を持つリソースをモデル化し、リソースのコピーが不要な場面でコピーのランタイムオーバーヘッドを排除できるようになった。これにより、性能を重視したコードをより簡潔に記述できる。
例えば、~Copyable
を使用すると、特定のオブジェクトが一度しかコピーされず、その後は他の場所で使い回すことができないという制約を与えることができる。これにより、リソースを厳密に管理し、パフォーマンスを向上させることが可能となる。
以下は、~Copyable
を使用した具体的なコード例である。
protocol Drinkable: ~Copyable {
consuming func use()
}
struct Coffee: Drinkable, ~Copyable { /* ... */ }
struct Water: Drinkable { /* ... */ }
func drink(item: consuming some Drinkable & ~Copyable) {
item.use()
}
drink(item: Coffee()) // 非コピー型の使用
drink(item: Water()) // コピー型の使用
この例では、Drinkable
プロトコルが定義されており、そのプロトコルに準拠する型にはuse
という消費的関数を実装する必要がある。また、Coffee
は非コピー型(~Copyable
)として定義されており、一方でWater
は通常のコピー型だ。このように、非コピー型とコピー型を区別することができ、パフォーマンスの最適化に役立つ。
Swift 6では、この非コピー型をジェネリクスシステムでサポートしているため、ジェネリックなコードでもコピー可能な型と非コピー型の両方に対応できる。例えば、ジェネリック関数で所有権に基づいた操作を行う場合、非コピー型を使用してパフォーマンスを向上させることができる。
さらに、Swift 6の標準ライブラリでも非コピー型が多用されており、新しい同期ライブラリにおけるAtomic
型や、Optional
およびResult
のような型が非コピー型として動作する。また、C++との相互運用性においても、非コピー型は重要な役割を果たしており、C++のムーブ専用型をSwift 6で効率的に扱うことができるようになっている。
C++との相互運用性
Swift 6では、C++のムーブ専用型や仮想メソッド、デフォルト引数、標準ライブラリ型(std::map
やstd::optional
)との相互運用性が強化された。これにより、SwiftとC++の統合がさらに進み、既存のC++プロジェクトとの連携が容易になった。
Embedded Swiftのプレビュー
Swift 6には、組み込みソフトウェア開発に適したSwift言語サブセットであるEmbedded Swiftのプレビューが含まれている。このツールチェーンは、ARMおよびRISC-Vのベアメタルターゲットをサポートし、小型のスタンドアロンバイナリを生成するため、メモリ制約のある環境に適している。
128ビット整数型の追加
Swift 6では、新たに符号付きおよび符号なしの128ビット整数型が追加され、すべてのSwiftプラットフォームで利用可能となった。
生産性向上のための新機能
Swift 6には、プログラミングの生産性を向上させるいくつかの新機能が追加されている。たとえば、シーケンス内の条件に合致する要素の数を簡単に数えるためのcount(where:)
や、パックイテレーション、アクセス制御のインポート、@attached(body)
マクロなどが含まれている。
Swift Testingライブラリの導入
Swift 6には、新しいテストライブラリであるSwift Testingが導入された。このライブラリは、テストを簡単に記述・整理できる表現力豊かなAPIを提供し、詳細なエラーメッセージを出力するマクロ#expect
を含む。
例:
@Test("Continents mentioned in videos", arguments: [
"A Beach",
"By the Lake",
"Camping in the Woods"
])
func mentionedContinents(videoName: String) async throws {
let videoLibrary = try await VideoLibrary()
let video = try #require(await videoLibrary.video(named: videoName))
#expect(video.mentionedContinents.count <= 3)
}
デバッグの改善
Swift 6では、新しいデバッグマクロが導入され、LLDBでオブジェクトの表示をカスタマイズできるようになった。これにより、p
コマンドでの表示やXcode、VSCodeの変数ビューでのオブジェクト表示が容易になる。
例:
@DebugDescription
struct Organization: CustomDebugStringConvertible {
var id: String
var name: String
var manager: Person
var debugDescription: String {
""#\(id) \(name) [\(manager.name)]""
}
}
Foundationのクロスプラットフォーム統一
Swift 6では、Foundationライブラリの実装がすべてのプラットフォームで統一され、macOSやiOSに加えて、LinuxおよびWindowsでも同様の機能が提供されるようになった。これにより、クロスプラットフォームでの一貫性と信頼性が向上している。
13. LinuxおよびWindows向けの改善
Swift 6では、LinuxとWindowsのサポートが強化され、DebianやFedoraに加えて、Ubuntu 24.04も公式にサポートされるようになった。また、Windows向けのSwiftパッケージマネージャは、複数コアでのビルド並列化がデフォルトとなり、ビルドパフォーマンスが大幅に向上している。
Swift 6の詳細については、Announcing Swift 6を参照していただきたい。