Swift Digest
Blog | Swift.org Blog

WWDC22 での Swift 言語アップデート

Swift language announcements from WWDC22

このダイジェストはClaude Opus 4.7 / 4.8によって生成されたものです(License)。原文はこちら

この記事の要点

この記事は公式のWWDCハイライトなので、ここでは Swift 利用者が押さえておくとよい注目トピックを選んで整理し、Swift Digest 内の関連ダイジェストへの導線を示します。網羅的な内容は元記事を参照してください。

注目トピック

コミュニティとツールの動き

Swift コミュニティの取り組みが広がり、特定領域に注力する新しいワークグループが発足しました。Swift.org Webサイトの進化を導く Website Workgroup、2言語間の相互運用を進める Swift and C++ interoperability ワークグループ、言語と標準ライブラリを統括する Language Workgroup です。2021年に発表された Swift Mentorship Program はさらに1年延長され、DocC・C++ 相互運用・Swift Webサイトといったテーマが追加されました。また Swift.org Webサイト自体がオープンソース化され、コミュニティからのコントリビューションを受け付けるようになっています。

Swift フレームワーク・パッケージ向けのドキュメントコンパイラ Swift-DocC もオープンソース化され、アプリプロジェクトのサポートや Objective-C / C API ドキュメントのサポートが追加されました。

Swift Package Manager の更新

Swift Package Manager にも重要なアップデートがありました。

言語機能のアップデート

Swift 5.7 では、細かな構文改善から大きなジェネリクス・並行処理の更新まで、幅広い言語機能が追加されました。元記事ではニュージーランドの「Bird of the Year」を題材にしたコード例で紹介されています。

if let の短縮構文(SE-0345: if let / guard let / while let でオプショナルをアンラップする際、右辺が同名の変数なら省略できます。

var startDate: Date?

if let startDate {
    print("Competition starts on \(startDate.formatted())")
}

複数文クロージャの型推論: if elsedo catch などの制御構文を含むクロージャでも、戻り値の型を手動で指定する必要がなくなりました。

let participants = ["Kororā", "Weka", "Pekapeka-tou-roa"]

let introductions = participants.map {
    if $0.hasPrefix("Pekapeka") {
        return "\($0) is a mammal"
    } else {
        return "\($0) is a bird"
    }
}

正規表現: regex リテラル(SE-0354)と RegexBuilder ライブラリ(SE-0351)により、強く型付けされたキャプチャを伴う文字列処理が可能になりました。名前付きキャプチャを結果から取り出せます。

let intent = "I vote for Pūkeko and Kea"

let regex = /I vote for (?<bird1>.+?) and (?<bird2>.+?)/

if let votes = try? regex.wholeMatch(in: intent) {
    print("Your first choice is \(votes.bird1)")
    print("Your second choice is \(votes.bird2)")
}

RegexBuilder を使うと、SwiftUI 風の宣言的な記述で正規表現を組み立てられます。

let word = OneOrMore(.word)
let regex = Regex {
    "I vote for "
    Capture { word }
    " and "
    Capture { word }
}

if let votes = try? regex.wholeMatch(in: intent) {
    let (_, bird1, bird2) = votes.output
    print("Your first choice is \(bird1)")
    print("Your second choice is \(bird2)")
}

ジェネリクスとプロトコル: プロトコルが primary associated types をサポートするようになり、プロトコル名の隣の山かっこで指定できます(SE-0346)。

protocol Contestant<Habitat> {
    associatedtype Habitat: Territory
    associatedtype Food

    var home: Habitat { get set }
    var favoriteFood: Food { get set }
    var name: String { get }
}

これにより、山かっこ構文で primary associated type を特定の型に制約できます。また、パラメータの型に some を使えるようになり(SE-0341)、ジェネリックパラメータが1か所でしか使われない場合は、関数にジェネリック制約を付けずに some で書けます。

func fundConservationEfforts(for animal: some Contestant) {
    establishProtectedAreas(in: animal.home)
    startIntensiveMonitoring(of: animal)
}

func fundReforestation(for animal: some Contestant<Forest>) {
    scheduleTreePlanting(in: animal.home)
}

existential 型にも大きな改善があり、any キーワードで existential 型を使う箇所を明示できるようになりました(SE-0335)。Selfassociatedtype 要件を持つプロトコルでも existential 型として扱えるようになり(SE-0309)、コレクションに入れたり変数や引数の型として使えます。

let contestants: [any Contestant] = [
    brownKiwi, ruru, whio
]

for contestant in contestants {
    fundConservationEfforts(for: contestant)
}

なお、any Contestant<Forest> のように existential 型へ制約を付ける機能は SE-0353 で導入されました。

並行処理: この年の並行処理アップデートは前年の変更を土台に、データ競合安全性に重点を置いています。

func announceWinner(_ winner: some Contestant) async throws {
    try await Task.sleep(
        until: .now + .seconds(10),
        tolerance: .seconds(1),
        clock: .suspending
    )

    print("The winner is \(winner.name)!")
}

このほか、パフォーマンス最適化、アクターの優先度付けと優先度逆転の回避、Instruments の Swift Concurrency テンプレートなど、並行処理まわりの多くの強化が行われています。さらに、ビルドの並列化による高速化、where 句やプロトコルを含む関数シグネチャの型チェック高速化、実行時のプロトコル適合チェックの最適化、標準ライブラリのサイズ削減と Linux 向けツールチェーン配布の整備など、多岐にわたる改善が紹介されています。

Swift Digestで詳しく読むべき項目

WWDC22 で取り上げられた主な言語機能は、それぞれ Swift Evolution Proposal のダイジェストがあります。