Swift Academy · レッスン

関数のwhere句

ジェネリック関数に細かな制約を追加します。

レッスン 2/413 ステップ

「関数のwhere句」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。

単純な制約を超えて

<T: Collection>のような制約は、T自体を表します。しかし、ElementのようなTの関連型を制約したい場合もあります。そのために使うのがwhere句です。

func sumInts<C: Collection>(_ c: C) -> Int where C.Element == Int {
    c.reduce(0, +)
}
print(sumInts([1, 2, 3]))

同一型要件

where C.Element == Intは、コレクションの要素が厳密にIntであることを要求し、整数に特化した処理を可能にします。

func describe<C: Collection>(_ c: C) -> String where C.Element == Int {
    "Sum is " + String(c.reduce(0, +))
}
print(describe(Set([1, 2, 3])))

要素に対するプロトコル要件

要素を特定の1つの型に限定するのではなく、プロトコルに適合することを要求できます。こちらのほうが柔軟です。

func joinAll<C: Collection>(_ c: C) -> String
    where C.Element: CustomStringConvertible {
    c.map { $0.description }.joined(separator: ", ")
}
print(joinAll([1, 2, 3]))

where句の位置

where句は、戻り値の型と関数本体の間に置きます。<>内の制約とwhere句の制約は、組み合わせて機能します。

func maxElement<C: Collection>(_ c: C) -> C.Element?
    where C.Element: Comparable {
    c.max()
}
print(maxElement([4, 9, 2])!)

2つの型パラメーターの関連付け

where句では、==を使って異なる2つのジェネリック型の要素型を関連付けることができます。

func combine<A: Collection, B: Collection>(_ a: A, _ b: B) -> [A.Element]
    where A.Element == B.Element {
    Array(a) + Array(b)
}
print(combine([1, 2], Set([3])))

複数のwhere条件

コンマで区切って複数の要件を記述し、複合的な制約を表現できます。

func report<C: Collection>(_ c: C)
    where C.Element: Comparable, C.Element: CustomStringConvertible {
    if let m = c.max() { print("max:", m.description) }
}
report([5, 1, 9])

ネストした関連型の制約

ネストしたコレクションを扱う場合などには、要素の要素を要求するように、さらに深い階層まで指定できます。

func flatten<C: Collection>(_ c: C) -> [Int]
    where C.Element: Collection, C.Element.Element == Int {
    c.flatMap { Array($0) }
}
print(flatten([[1, 2], [3]]))

Equatable要素とwhere

Equatableの要素を要求すると、ジェネリックコレクションを検索できます。

func indexOf<C: Collection>(_ x: C.Element, in c: C) -> C.Index?
    where C.Element: Equatable {
    c.firstIndex(of: x)
}
if let i = indexOf(2, in: [1, 2, 3]) { print("found") }

whereを使ったジェネリックメソッド

ジェネリック型の内部にあるメソッドでもwhereを使えます。特定の要素型に限って機能を追加する場合によく使用します。

struct Wrap<T> {
    let items: [T]
    func total() -> Int where T == Int { items.reduce(0, +) }
}
print(Wrap(items: [1, 2, 3]).total())

可読性の向上

複雑な制約は、山かっこ内に詰め込むよりもwhere句に記述したほうが読みやすくなります。関連型に関する条件が複数ある場合は特に効果的です。

func first<C: Collection>(_ c: C) -> String
    where C.Element: CustomStringConvertible {
    c.first.map { $0.description } ?? "empty"
}
print(first([10, 20]))

標準ライブラリでのwhere

シーケンスのシーケンスに対するjoined()のようなメソッドでは、要件を正確に表現するために、内部でwhere句を使用しています。

let nested = [[1, 2], [3, 4]]
print(Array(nested.joined()))

理解度チェック

関数のwhere句についての理解度を確認しましょう。

まとめ

where句を使うと、ジェネリック型の関連型を制約できます。要素を特定の型(== Int)にしたり、プロトコル(: Comparable)に適合させたり、2つのパラメーターの要素を関連付けたり、ネストした関連型まで指定したりできます。where句はシグネチャの後に置き、複雑な制約を読みやすくします。

無料で開始

AI チューターと学ぶ Swift — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
122
レッスン
409

よくある質問

「関数のwhere句」レッスンは無料ですか?

はい。「関数のwhere句」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。

「関数のwhere句」で何を学びますか?

ジェネリック関数に細かな制約を追加します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Swift Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「関数のwhere句」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSwift Academyレッスンでコードを書いて実行できますか?

はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 型パラメータの制約
  2. 関数のwhere句
  3. 関連型の制約
  4. ジェネリックなサブスクリプトとエクステンション
← Swift Academyに戻る