再帰的制約と高階ジェネリック
再帰的制約 (例:ネストしたシーケンス)と、ジェネリックなクロージャや関数を引数に取る 高階ジェネリック 関数を記述します。
「再帰的制約と高階ジェネリック」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン2/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全3レッスンが含まれています。
概要と目的
このレッスンでは次の内容を扱います。
- 再帰的制約: ネストされたジェネリックメンバーに対する制約(例: Sequence of Sequence)。
- 高階ジェネリクス: ジェネリックなクロージャや関数を受け取るジェネリック関数。
ネストされたシーケンス(平坦化)
これは典型的な再帰的制約です。2階層を深く反復できるように、C.Element: Sequenceを要求します。
// Works for any Collection whose elements are Sequences
func flatten<C: Collection>(_ c: C) -> [C.Element.Element]
where C.Element: Sequence {
var result: [C.Element.Element] = []
result.reserveCapacity(c.reduce(0) { $0 + ($1 as AnySequence<C.Element.Element>).underestimatedCount })
for inner in c {
for e in inner { result.append(e) }
}
return result
}
let nested = [[1,2], [3], [4,5]]
print(flatten(nested)) // [1,2,3,4,5]ネストされたデータをジェネリックにマッピングする
C: CollectionとC.Element: Collectionという2つの制約を付けることで、各階層でmapを呼び出せます。
// Map over a two-level structure without fixing concrete types
func mapNested<C: Collection, R>(_ c: C, _ transform: (C.Element.Element) -> R) -> [[R]]
where C.Element: Collection {
return c.map { inner in inner.map(transform) }
}
let doubled = mapNested([[1,2],[3]], { $0 * 2 })
print(doubled) // [[2,4],[6]]compose(f,g)
高階ジェネリクスでは、関数自体を関数に対するジェネリックな対象として扱い、composeのような再利用可能なパイプラインを構築します。
// Compose two generic transforms that work on the same element type
func compose<A, B, C>(
_ f: @escaping (B) -> C,
_ g: @escaping (A) -> B
) -> (A) -> C {
{ a in f(g(a)) }
}
let toString: (Int) -> String = { "\\($0)" }
let length: (String) -> Int = { $0.count }
let intToLen = compose(length, toString)
print(intToLen(1234)) // 4ジェネリックなクロージャパラメータ
クロージャfもジェネリックパラメータです。where制約によって型の柔軟性を保ちます。
// A generic "transform each" that accepts ANY transform (generic in T/U)
func transformEach<T, U, C: Collection>(_ c: C, using f: (T) -> U) -> [U]
where C.Element == T {
var out: [U] = []
out.reserveCapacity(c.count)
for x in c { out.append(f(x)) }
return out
}
let words = ["swift","kit"]
print(transformEach(words, using: { $0.uppercased() })) // ["SWIFT","KIT"]ガイドライン
ヒント:
- 必要最小限の制約を記述してください(
SequenceとCollectionの使い分け)。 - 読みやすさのためにwhere句を優先してください。
- 複数の具体的な型でテストし、汎用性を確認してください。
- 前提(例: 要素の順序や一意性)をドキュメント化してください。
高階ジェネリクスの定義
確認問題: 関数を高階ジェネリック関数にする要素は何ですか?
まとめ
まとめ: ネストされたジェネリクスを扱うには再帰的制約(例: C.Element: Sequence)を使用し、再利用可能な関数パイプラインをすっきりと構成するには高階ジェネリクスを使用します。
よくある質問
「再帰的制約と高階ジェネリック」レッスンは無料ですか?
はい。「再帰的制約と高階ジェネリック」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全3レッスンが含まれています。
「再帰的制約と高階ジェネリック」で何を学びますか?
再帰的制約 (例:ネストしたシーケンス)と、ジェネリックなクロージャや関数を引数に取る 高階ジェネリック 関数を記述します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/3です。
「再帰的制約と高階ジェネリック」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 条件付き準拠
- 再帰的制約と高階ジェネリック
- エクステンションでのwhere句