関数のwhere句
ジェネリック関数に細かな制約を追加します。
「関数の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フィードバックを取得できます。ローカル設定は不要です。