Generics
Genericsは鬼門だわ
昨日に引き続き https://docs.swift.org/swift-book/LanguageGuide/Generics.html を読む。
- genericな関数
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {…}
- 使うときは
swapTwoValues(&someValue, &anotherValue)
適切に型推論される - 実際にはSwift標準ライブラリの
swap(_:_:)
を使うが良い - 総称型
struct Stack<Element> {…}
- 総称型へのextension
extension Stack {…}
- 型の制約
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {…}
func findIndex<T: Equatable>(of valueToFind: T, in array:[T]) -> Int? {…}
- プロトコルは総称型にできないので、替わりに
associatedtype
を使う - プロトコルをconformする実装では
typealias 抽象型 = 具体型
- ↑型推論がうまくいけば typealias はなくてもいける
- 既存の型へのextensionでプロトコルをconformするとき、関連する型も含まれる
- プロトコルで関連する型の制約
associatedtype Item: Equatable
- プロトコルで関連する型の制約
associatedtype T: U where T.Item == Self.Item
- generic関数で制約
func f<C1: C, C2: C> (_ a: C1, _ b: C2) -> Bool where C1.Item == C2.Item, C1.Item: Equatable {}
- 総称型へのextensionで型パラメータの制約
extension Stack where Element: Equatable {…}
- プロトコルへのextensionで関連型の制約
extension Container where Item == Double {…}
- プロコトルへのextension中のsubscriptにwhere句
subscript<Indices: Sequence>(indices: Indices) -> [Item] where Indices.Iterator.Element == Int {…}
- プロコトルへのextension中のsubscriptにwhere句
protocolを既存の型にextentionで適合させるときに 思いもよらない組み合わせを生み出しそうで恐ろしい。
たぶん自分ではそんなに凝ったことは書かないと思うので問題はないけど 他人が書いたコードを読める自信は無い。