Swift 6の概要
2024年9月、Xcode 16と共にSwift 6がリリースされました。このバージョンの最大の特徴は、データ競合を完全にコンパイル時に防止できるようになったことです。
データ競合の完全な防止
Swift 6言語モード
Swift 6では、データ競合がコンパイルエラーになります。
// Package.swift で Swift 6モードを有効化
// swift-tools-version: 6.0
var counter = 0
func increment() async {
counter += 1 // エラー: データ競合の可能性
}
Sendableの厳格化
// Sendableでないオブジェクトを並行コンテキストに渡せない
class UnsafeClass {
var value = 0
}
func example() async {
let obj = UnsafeClass()
Task {
obj.value += 1 // エラー: UnsafeClassはSendableでない
}
}
// 解決策1: Sendable準拠
final class SafeClass: Sendable {
let value: Int // 不変にする
init(value: Int) { self.value = value }
}
// 解決策2: アクターを使用
actor Counter {
var value = 0
func increment() { value += 1 }
}
型付きthrows
エラーの型を明示的に指定できるようになりました。
// 従来: anyエラー
func legacyParse() throws -> Data {
throw ParseError.invalidFormat
}
// Swift 6: 型付きthrows
enum ParseError: Error {
case invalidFormat
case emptyInput
}
func parse() throws(ParseError) -> Data {
throw .invalidFormat
}
// 呼び出し側で型が分かる
do {
let data = try parse()
} catch {
// errorの型はParseError
switch error {
case .invalidFormat:
print("フォーマットエラー")
case .emptyInput:
print("入力が空")
}
}
never を使った絶対に失敗しない関数
// 絶対にエラーを投げない
func safeParse() throws(Never) -> Data {
return Data()
}
// tryなしで呼び出せる
let data = safeParse()
128ビット整数
let big: Int128 = 170_141_183_460_469_231_731_687_303_715_884_105_727
let ubig: UInt128 = 340_282_366_920_938_463_463_374_607_431_768_211_455
print(big.bitWidth) // 128
Embedded Swift
リソース制限のある環境(マイクロコントローラーなど)向けのSwiftサブセット。
// Embedded Swift用のコード
@main
struct LEDBlink {
static func main() {
let led = DigitalOutput(pin: 13)
while true {
led.toggle()
sleep(milliseconds: 500)
}
}
}
# Embedded Swiftでビルド
swiftc -enable-experimental-feature Embedded -target armv7em-none-eabi main.swift
C++相互運用性の改善
C++からSwiftへ
// C++ヘッダー
class CppCounter {
public:
CppCounter(int initial);
void increment();
int getValue() const;
private:
int value;
};
// Swiftから使用
import CppCounter
let counter = CppCounter(42)
counter.increment()
print(counter.getValue()) // 43
SwiftからC++へ
// Swift
@_expose(Cxx)
public func swiftFunction() -> Int {
return 42
}
// C++から呼び出し
#include "MyModule-Swift.h"
int result = swiftFunction();
同期のためのMutexとAtomic
import Synchronization
// Mutex
let mutex = Mutex(initialValue: 0)
mutex.withLock { value in
value += 1
}
// Atomic
let atomic = Atomic<Int>(0)
atomic.wrappingAdd(1, ordering: .relaxed)
let current = atomic.load(ordering: .acquiring)
段階的なマイグレーション
Swift 5モードでの警告
// Package.swift
let package = Package(
swiftLanguageVersions: [.v5], // まだSwift 5
// ...
)
// 並行性警告を有効化
swiftSettings: [
.enableUpcomingFeature("StrictConcurrency")
]
ファイル単位での移行
// 特定のファイルだけSwift 6モードに
// ファイル先頭に追加
// swift-tools-version: 6.0
Xcode 16との統合
ビルド設定
SWIFT_VERSION = 6.0
SWIFT_STRICT_CONCURRENCY = complete
新しい警告と修正提案
// Xcodeが自動修正を提案
class MyClass {
var data: [Int] = []
func process() async {
// 警告 + Fix-it: @MainActor を追加
data.append(1)
}
}
パフォーマンス改善
| 項目 | Swift 5.10 | Swift 6 |
|---|---|---|
| コンパイル速度 | 基準 | +15% |
| バイナリサイズ | 基準 | -10% |
| 実行速度 | 基準 | +5% |
まとめ
Swift 6は、言語の安全性を新たなレベルに引き上げました。
- データ競合防止: コンパイル時に完全に検出
- 型付きthrows: エラーハンドリングの改善
- 128ビット整数: 大きな数値のサポート
- Embedded Swift: 組み込みシステム対応
- C++相互運用: より深い連携
既存のプロジェクトは段階的に移行でき、Swift 5との互換性も維持されています。
← 一覧に戻る