関連型の制約
ジェネリックコンテキストで関連型を制限します。
「関連型の制約」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。
関連型のまとめ
プロトコルでは、associatedtypeを使って関連型を宣言できます。これは、適合する型が具体的な型を割り当てるプレースホルダーです。コンテナープロトコルのElementが典型的な例です。
protocol Container {
associatedtype Item
var count: Int { get }
func item(at i: Int) -> Item
}具体的な型での適合
適合する型が関連型を確定します。多くの場合、型の使われ方から関連型が推論されます。
protocol Container {
associatedtype Item
func item(at i: Int) -> Item
}
struct IntBox: Container {
let values: [Int]
func item(at i: Int) -> Int { values[i] }
}
print(IntBox(values: [10, 20]).item(at: 1))関連型の制約
宣言に制約を直接追加できます。associatedtype Item: Comparableとすると、適合するすべての型のアイテム型が比較をサポートするよう要求されます。
protocol Sorted {
associatedtype Item: Comparable
var items: [Item] { get }
}
struct Nums: Sorted { let items: [Int] }
print(Nums(items: [3, 1, 2]).items.sorted())制約の利用
関連型に制約があるため、プロトコル拡張はその機能を前提にできます。
protocol Sorted {
associatedtype Item: Comparable
var items: [Item] { get }
}
extension Sorted {
var smallest: Item? { items.min() }
}
struct Nums: Sorted { let items: [Int] }
print(Nums(items: [5, 2, 8]).smallest!)associatedtypeでのwhere
Swiftでは、関連型にwhere句を付けて、別の関連型やネストした型との関係を指定することもできます。
protocol Sequence2 {
associatedtype Element
associatedtype Iterator: IteratorProtocol where Iterator.Element == Element
}別のプロトコルへの制約
関連型が自分で定義したプロトコルに適合することを要求でき、機能を段階的に組み合わせられます。
protocol HasName { var name: String { get } }
protocol Registry {
associatedtype Entry: HasName
var entries: [Entry] { get }
}
struct User: HasName { let name: String }
struct Users: Registry { let entries: [User] }
print(Users(entries: [User(name: "Ada")]).entries[0].name)複数の関連型
プロトコルでは複数の関連型を宣言でき、それぞれに個別の制約を指定できます。
protocol Mapping {
associatedtype Key: Hashable
associatedtype Value
func value(for k: Key) -> Value?
}
struct Phonebook: Mapping {
let data: [String: Int]
func value(for k: String) -> Int? { data[k] }
}
print(Phonebook(data: ["x": 1]).value(for: "x")!)関連型のデフォルト
=を使って関連型にデフォルトを指定できます。適合する型が別の型を指定していない場合に、そのデフォルトが使用されます。
protocol Producer {
associatedtype Output = String
func make() -> Output
}
struct Hello: Producer {
func make() -> String { "hi" }
}
print(Hello().make())制約によるジェネリックアルゴリズム
関連型に制約があると、プロトコル拡張で、すべての適合する型に共通する実用的なアルゴリズムを実装できます。
protocol Scored {
associatedtype Score: Comparable
var scores: [Score] { get }
}
extension Scored {
var best: Score? { scores.max() }
}
struct Game: Scored { let scores: [Int] }
print(Game(scores: [10, 40, 25]).best!)拡張での同一型制約
プロトコルの外部では、プロトコルを拡張する際に関連型へさらに制約を追加できます。
protocol Box2 {
associatedtype Content
var content: Content { get }
}
extension Box2 where Content == Int {
var doubled: Int { content * 2 }
}
struct IB: Box2 { let content: Int }
print(IB(content: 7).doubled)なぜ制約するのか
関連型を制約することで、プロトコルは汎用性と強力な機能を両立できます。制約は、拡張や呼び出し側が信頼できる保証です。
protocol Listy {
associatedtype E: Equatable
var elements: [E] { get }
}
extension Listy {
func has(_ x: E) -> Bool { elements.contains(x) }
}
struct L: Listy { let elements: [String] }
print(L(elements: ["a", "b"]).has("b"))理解度チェック
関連型の制約についての理解度を確認しましょう。
まとめ
関連型には、直接制約(associatedtype Item: Comparable)を指定したり、where句で関連付けたり、プロトコルへの適合を要求したり、=でデフォルトを指定したりできます。複数の関連型を宣言し、拡張で制約をさらに絞り込むことも可能です。制約により、プロトコル拡張で型安全な共通アルゴリズムを実装できます。
よくある質問
「関連型の制約」レッスンは無料ですか?
はい。「関連型の制約」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。
「関連型の制約」で何を学びますか?
ジェネリックコンテキストで関連型を制限します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「関連型の制約」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。