Kotlinでoutキーワードの意味が理解できず、見つかりませんでした。
ここで例を確認できます:
List<out T>
誰かがこの意味を説明できるなら。本当にありがたいです。
この署名では:
List<out T>
あなたはこれを行うことができます:
val doubleList: List<Double> = listOf(1.0, 2.0)
val numberList: List<Number> = doubleList
つまり、[〜#〜] t [〜#〜]はcovariant:
型パラメーター[〜#〜] t [〜#〜]がクラス[〜#〜]の場合c [〜#〜]が宣言されているout、C <Base> は安全にsupertypeofC <Derived>。
これは、inとは対照的です。
Comparable<in T>
あなたはこれを行うことができます:
fun foo(numberComparable: Comparable<Number>) {
val doubleComparable: Comparable<Double> = numberComparable
// ...
}
つまり、[〜#〜] t [〜#〜]はcontravariant:
型パラメーター[〜#〜] t [〜#〜]がクラス[〜#〜]の場合c [〜#〜]が宣言されているin、C <Derived> は安全にsupertypeofC <Base>。
それを覚える別の方法:
消費者in、生産者out。
Kotlin Generics Variance を参照してください
----------------- 2019年1月4日に更新-----------------
「Consumer in、Producer out」の場合、Producerからのみ読み取る-型Tの結果を取得するメソッドを呼び出すコンシューマーにのみ書き込む-タイプTのパラメーターを渡すことでメソッドを呼び出します。
List<out T>
の例では、これができることは明らかです。
val n1: Number = numberList[0]
val n2: Number = doubleList[0]
したがって、List<Double>
が期待されるときにList<Number>
を提供することは安全です。したがって、List<Number>
はList<Double>
のスーパータイプですが、その逆はできません。
Comparable<in T>
の例:
val double: Double = 1.0
doubleComparable.compareTo(double)
numberComparable.compareTo(double)
したがって、Comparable<Number>
が期待されるときにComparable<Double>
を提供することは安全です。したがって、Comparable<Double>
はComparable<Number>
のスーパータイプですが、その逆はできません。
List<out T> is like List<? extends T> in Java
そして
List<in T> is like List<? super T> in Java
たとえば、コトリンでは次のようなことができます
val value : List<Any> = listOf(1,2,3)
//since List signature is List<out T> in Kotlin
参照してください kotlinのマニュアル
Kotlin
List<out T>
タイプは、サイズ、取得などの読み取り専用操作を提供するインターフェイスです。 Javaと同様に、Collection<T>
を継承し、次にIterable<T>
を継承します。リストを変更するメソッドは、MutableList<T>
インターフェイスによって追加されます。このパターンは、Set<out T>/MutableSet<T>
およびMap<K, out
V>/MutableMap<K, V>
にも当てはまります
この、
Kotlinには、この種のことをコンパイラーに説明する方法があります。これは、宣言サイトの分散と呼ばれます。Sourceの型パラメーターTに注釈を付けて、
Source<T>
のメンバーからのみ返され(生成され)、決して消費されないようにすることができます。これを行うには、out修飾子を提供します。> abstract class Source<out T> { > abstract fun nextT(): T } > > fun demo(strs: Source<String>) { > val objects: Source<Any> = strs // This is OK, since T is an out-parameter > // ... }
一般的な規則は次のとおりです。クラス
T
の型パラメーターC
が宣言されている場合、C
のメンバーのアウトポジションでのみ発生しますが、C<Base>
は安全にC<Derived>
のスーパータイプにすることができます。「賢い言葉」では、クラス
C
がパラメーターT
で共変である、またはT
が共変型パラメーターであると言います。 CはT
の消費者ではなく、Tの生産者であると考えることができます。 out修飾子はバリアンスアノテーションと呼ばれ、型パラメーター宣言サイトで提供されるため、宣言サイトのバリアーについて説明します。これは、型の使用法のワイルドカードが型を共変にするJavaの使用サイトの相違とは対照的です。