元の記事 → Swift to Kotlinチートシート
functionのGenerics
fun <T> get(arg: T): T {
return arg
}
classのGenerics
class Bar<T> {}
Generics型の制約
class Bar<T: View> {}
複数制約を設ける場合は where で書く。
class Bar<T> where T: View, T: TypeCode {}
何も制約を設けない場合は Any? 扱い。
以下のケースではKClassのTがnullを許容しないので、少なくとも optional を外して、T: Anyにしないとコンパイルが通らない。
fun <T: Any> get(type: KClass<T>) : T {
return type.java.newInstance()
}
Generics型のインスタンス化
Generics型のインスタンス化はできないっぽい。
以下のようにTypeを受け取ってオブジェクトを作ることはできる。
fun <T: Any> get(type: KClass<T>) : T {
return type.java.newInstance()
}
Genericsのワイルドカード
Javaで言う Class> は アスタリスクを使って Class<*>のように書く。
このアスタリスクはout Any?を表す。
out なのでGenerics型は戻り値にしか使えない。
Generics Typeからクラスオブジェクトを取得する
T::class のように Genericsの型からクラスオブジェクトを取得するのは、基本的に無理。
inline fun <reified T>foo() {
System.out.println(T::class)
}
上記のようにfunction を inline にしてGenericsの型に reified をつけるとクラスオブジェクトを取得できるが、inlineのファンクションは色々と制限があり、使うのが難しい場合がある。
また、今のところクラスに指定したGenericsパラメータからはクラスオブジェクトを取得する術がないっぽい。
class Foo<T> {
fun test() {
// ここで T::class を使うすべがない
}
}
declaration-site variance
Genericsパラメーターを制約付きWildcardにしたい場合、型の前に out を記載する。
List<? extends Number> b = a;
val b: ArrayList<out Number> = a
詳細は以下に書いているがまだちゃんと理解できていない。
https://kotlinlang.org/docs/reference/generics.html#variance