Kotlin学習ノート(九)【汎用】
Kotlin汎用
汎用型、すなわち「パラメータ化タイプ」は、タイプをパラメータ化し、クラス、インタフェース、メソッドに使用できます.Javaと同様に、Kotlinも汎用型を提供し、タイプの安全を保証し、タイプの強転の悩みを解消します.汎用クラスを宣言します.
クラスのインスタンスを作成するには、タイプパラメータを指定する必要があります.
次の例では、汎用クラスBoxに整数データと文字列を入力します.
出力結果:1 qfxl
汎用タイプ変数を定義し、タイプパラメータを完全に明記したり、コンパイラがタイプパラメータを自動的に推定したり、タイプパラメータを省略したりすることができます.Kotlin汎用関数の宣言はJavaと同じで、タイプパラメータは関数名の前に配置します.
出力結果:1 qfxl
汎用関数を呼び出す場合、タイプパラメータを推定できる場合は、汎用パラメータを省略できます.次の例では、入力された異なるタイプに応じて対応する汎用関数
出力結果:
T is String upperCase is QFXL T is Int value is 26 T is not String or Int
汎用拘束
汎用コンストレイントを使用して、所定のパラメータで使用できるタイプを設定できます.Kotlinで使用:汎用タイプの上限を拘束します.最も一般的な制約は上界(upper bound):
ComparableのサブタイプはTに取って代わることができる.例:
デフォルトの上界はAny?です.複数の上界コンストレイントの場合、where句を使用します.
ひずみ
Kotlinにはワイルドカードタイプはなく、宣言箇所型変(declaration-site variance)とタイプ投影(type projections)の2つの他のものがあります.
宣言のタイプ変異は、コヒーレント注釈修飾子:in、out、消費者in、生産者outを使用します.
コヒーレンス(covariant:Foo=Foo)
協変は親類の汎用型から具体的なサブクラスに変わり、KotlinはJava中の
**逆変換(contravariance:Foo=Foo)逆変換サブタイプ型が特定の親になり、KotlinはJavaの代わりにoutキーを提供します.
汎用型、すなわち「パラメータ化タイプ」は、タイプをパラメータ化し、クラス、インタフェース、メソッドに使用できます.Javaと同様に、Kotlinも汎用型を提供し、タイプの安全を保証し、タイプの強転の悩みを解消します.汎用クラスを宣言します.
class Box<T>(t: T) {
var value = t
}
クラスのインスタンスを作成するには、タイプパラメータを指定する必要があります.
val box: Box = Box(1)
//
val box = Box(1) // ,1 Int, Box。
次の例では、汎用クラスBoxに整数データと文字列を入力します.
fun main(args: Array) {
val boxInt: Box = Box(1)
val boxString: Box = Box("qfxl")
println(boxInt.value)
println(boxString.value)
}
class Box(t: T) {
var value = t
}
出力結果:1 qfxl
汎用タイプ変数を定義し、タイプパラメータを完全に明記したり、コンパイラがタイプパラメータを自動的に推定したり、タイプパラメータを省略したりすることができます.Kotlin汎用関数の宣言はJavaと同じで、タイプパラメータは関数名の前に配置します.
fun main(args: Array) {
val boxInt = boxIn(1)
val boxString = boxIn("qfxl") // String
println(boxInt.value)
println(boxString.value)
}
class Box<T>(t: T) {
var value = t
}
fun boxIn(t: T) = Box(t)
出力結果:1 qfxl
汎用関数を呼び出す場合、タイプパラメータを推定できる場合は、汎用パラメータを省略できます.次の例では、入力された異なるタイプに応じて対応する汎用関数
doPrint
が作成されます.fun main(args: Array) {
val name = "qfxl"
val age = 26
val bo = false
doPrint(name)
doPrint(age)
doPrint(bo)
}
fun doPrint(t: T) {
when (t) {
is String -> println("T is String upperCase is ${t.toUpperCase()}")
is Int -> println("T is Int value is $t")
else -> println("T is not String or Int")
}
}
出力結果:
T is String upperCase is QFXL T is Int value is 26 T is not String or Int
汎用拘束
汎用コンストレイントを使用して、所定のパラメータで使用できるタイプを設定できます.Kotlinで使用:汎用タイプの上限を拘束します.最も一般的な制約は上界(upper bound):
fun > sort(list: List) {
// ……
}
ComparableのサブタイプはTに取って代わることができる.例:
sort(listOf(1, 2, 3)) // OK。Int Comparable
sort(listOf(HashMap() )) // :HashMap Comparable>
デフォルトの上界はAny?です.複数の上界コンストレイントの場合、where句を使用します.
fun <T> cloneWhenGreater(list: List<T>, threshold: T): List<T>
where T : Comparable, Cloneable {
return list.filter(it > threshold).map(it.clone())
}
ひずみ
Kotlinにはワイルドカードタイプはなく、宣言箇所型変(declaration-site variance)とタイプ投影(type projections)の2つの他のものがあります.
宣言のタイプ変異は、コヒーレント注釈修飾子:in、out、消費者in、生産者outを使用します.
コヒーレンス(covariant:Foo=Foo)
協変は親類の汎用型から具体的なサブクラスに変わり、KotlinはJava中の
in
のワイルドカード文法の代わりに extends E>
のキーワードを提供し、同時にJava中の汎用型の消去中に発生したタイプ変換の安全を解決するために、KotlinはC#の戦略を採用した.すなわち、協変型は消費者として、読み取るしかなく書き込むことができない.out
を使用して、1つのタイプのパラメータをコヒーレントにします.コヒーレントタイプのパラメータは出力としてのみ使用できます.戻り値のタイプとして使用できますが、パラメータのタイプとして使用できません.//
class Runoob(val a: A) {
fun foo(): A {
return a
}
}
fun main(args: Array<String>) {
var strCo: Runoob<String> = Runoob("a")
var anyCo: Runoob = Runoob("b")
anyCo = strCo
println(anyCo.foo()) // a
}
**逆変換(contravariance:Foo=Foo)逆変換サブタイプ型が特定の親になり、KotlinはJavaの代わりにoutキーを提供します.