Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
ジェネリクス — 基本
Kotlinのジェネリクスは型パラメーターを使って、型安全なコレクションやアルゴリズムを定義する仕組みです。関数やクラスに型パラメーター『<T>』を付けることで、様々な型に対応できます。
構文
// ジェネリクス関数
fun <T> 関数名(引数: T): T { return 引数 }
// ジェネリクスクラス
class Box<T>(val value: T)
// 型制約(T は Comparable を実装した型のみ)
fun <T : Comparable<T>> max(a: T, b: T): T = if (a > b) a else b
// 複数の型パラメーター
fun <K, V> pair(key: K, value: V): Pair<K, V> = Pair(key, value)
構文一覧
| 構文 | 概要 |
|---|---|
| <T> | 型パラメーターの宣言です。任意の型を受け付けます。 |
| <T : 上限型> | 型制約です。T は上限型のサブタイプのみ使えます。 |
| where T : 型1, T : 型2 | 複数の型制約を指定します。 |
| Box<Int> | 型引数を指定してジェネリクスを使います。 |
| Box<*> | スター投影。型が不明な場合に使います(Java の Box<?> 相当)。 |
サンプルコード
// ジェネリクス関数 — 任意の型の最初の要素を返します。
fun <T> firstOrNull(list: List<T>): T? = list.firstOrNull()
// 型制約付き — Comparable を実装した型の最大値を求めます。
fun <T : Comparable<T>> maxOf(a: T, b: T): T = if (a > b) a else b
// ジェネリクスクラス
class Stack<T> {
private val items = mutableListOf<T>()
fun push(item: T) { items.add(item) }
fun pop(): T? = if (items.isEmpty()) null else items.removeAt(items.lastIndex)
fun peek(): T? = items.lastOrNull()
val size: Int get() = items.size
}
// where 句で複数制約を指定します。
fun <T> printIfComparableAndSerializable(value: T)
where T : Comparable<T>, T : java.io.Serializable {
println(value)
}
fun main() {
println(firstOrNull(listOf(1, 2, 3))) // 1
println(firstOrNull(emptyList<String>())) // null
println(maxOf(3, 7)) // 7
println(maxOf("apple", "mango")) // mango
val stack = Stack<String>()
stack.push("a")
stack.push("b")
stack.push("c")
println(stack.pop()) // c
println(stack.peek()) // b
println(stack.size) // 2
printIfComparableAndSerializable(42) // 42
printIfComparableAndSerializable("hello") // hello
}
概要
ジェネリクスを使うと型ごとに別々の関数やクラスを定義する必要がなく、型安全なコードを再利用できます。Kotlinの型推論により、多くの場合は型引数を省略できます。
型パラメーターはデフォルトで『Any?』が上限型のため、null 許容です。『<T : Any>』と書くと non-null 型のみを受け付けます。
ジェネリクスの変位指定は共変 / 反変を、実行時の型情報保持はreified 型パラメーターを参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。