今日でGenericsの章が終わった.なかなかややこしかったのでまとめてみる.
タイプパラメータ
まず,Swiftのタイプパラメータ*1は3種類ある.
それぞれこんな感じ.
func genericFuncion<T, U>(_ t: T, u: U) {} struct GenericType<T, U> {} protocol Prot { associatedtype T associatedtype U }
generic functionっぽいことは関数様のものにも使えるのでジェネリックなsubscriptとかinitを作れる.
制約
タイプパラメータには制約をつけることができてこっちは2種類ある.
それぞれこんな感じ.
T: Sequence
がType Constraintでwhere ....
がGeneric where Clause.
func genericFuncion<T: Sequence, U>(_ t: T, u: U) where U: AnyObject, T.Element == U {} struct GenericType<T: Sequence, U> where U: AnyObject, T.Element == U {} protocol Prot { associatedtype T: Sequence associatedtype U: AnyObject where T.Element == U }
文法上問題はないが,Generic Where Clausesに以下のように書いてあるのでジェネリックほげほげの制約に使うのは良くないのか?と思うけどGeneric Where Clausesを使わないと表せない制約もあるのでよくわからん.
Type constraints, as described in Type Constraints, enable you to define requirements on the type parameters associated with a generic function, subscript, or type.
It can also be useful to define requirements for associated types. You do this by defining a generic where clause. [https://docs.swift.org/swift-book/LanguageGuide/Generics.html#ID192
Extensions with a Generic Where Clause
Generic Where Clauseはextensionのときにも使うことができる.これを使うとある条件のときだけメソッドを定義するということができる.
extension GenericType where T.Element == Some { func printSome() { print("T is Some") } } extension GenericType where T.Element == Another { func printAnother() { print("T is Another") } } class Some {} class Another {} GenericType<[Some], Some>().printSome() // T is Some // GenericType<[Another], Another>().printSome() // Referencing instance method 'printSome()' on 'GenericType' requires the types 'Another' and 'Some' be equivalent
加えてこれをメソッドごとに書くこともできる.
extension GenericType { func printSome() where T.Element == Some { print("T is Some") } func printAnother() where T.Element == Another { print("T is Another") } } class Some {} class Another {} GenericType<[Some], Some>().printSome() // T is Some // GenericType<[Another], Another>().printSome() // Referencing instance method 'printSome()' on 'GenericType' requires the types 'Another' and 'Some' be equivalent
*1:これは一般的な呼称?