Kotlin ジェネリック(Generic)
ジェネリッククラス
引数をAny型として受け取り、Any型のプロパティに保存することで、Int、Char、Stringなど、さまざまな型に応じたクラスや関数を定義できる。
class Foo(val value: Any)
fun main() {
val a1 = Foo(123)
println(a1.value) // 123
}
しかしvalueはAny型なので、次のようにvalueに+ 1演算を行うとエラーが発生する。
class Foo(val value: Any)
fun main() {
val a1 = Foo(123)
println(a1.value + 1) // Error
}
<T>でジェネリック型を定義することで、valueはInt、Char、Stringなど、引数に応じた型のプロパティとして扱われ、この問題を解決できる。
class Foo<T>(val value: T)
fun main() {
val a1 = Foo(123)
println(a1.value + 1) // 124
}
次のように型に制限をかけることができる。ここではIntやDoubleなど、Numberのサブクラスに制限している。
class Foo<T: Number>(val value: T)
ジェネリック関数
関数でもジェネリックを使用できる。次は任意の型Tの引数を受け取り、T型の値を返す関数である。
fun <T> foo(x: T): T { ... }
呼び出し時に型を指定するが、引数によって型が明確な場合は省略できる。
foo<Int>(123)
foo<String>("ABC")
foo(123)
foo("ABC")
次のように型に制限をかけることができる。ここではIntやDoubleなど、Numberのサブクラスに制限している。
fun <T: Number> foo(x: T): T { ... }
制約条件を複数指定するにはwhereを使用する。
fun <T> foo(x: T) where T: Runnable, T: Cancellable { ... }