web-dev-qa-db-ja.com

kotlinのoutキーワードとは

Kotlinでoutキーワードの意味が理解できず、見つかりませんでした。

ここで例を確認できます:

List<out T>

誰かがこの意味を説明できるなら。本当にありがたいです。

48
Akshay Sood

この署名では:

List<out T>

あなたはこれを行うことができます:

val doubleList: List<Double> = listOf(1.0, 2.0)
val numberList: List<Number> = doubleList

つまり、[〜#〜] t [〜#〜]covariant

型パラメーター[〜#〜] t [〜#〜]がクラス[〜#〜]の場合c [〜#〜]が宣言されているoutC <Base> は安全にsupertypeofC <Derived>

これは、inとは対照的です。

Comparable<in T>

あなたはこれを行うことができます:

fun foo(numberComparable: Comparable<Number>) {
  val doubleComparable: Comparable<Double> = numberComparable
  // ...
}

つまり、[〜#〜] t [〜#〜]contravariant

型パラメーター[〜#〜] t [〜#〜]がクラス[〜#〜]の場合c [〜#〜]が宣言されているinC <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>のスーパータイプですが、その逆はできません。

39
Andrew Feng
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
44
DmitryBorodin

参照してください kotlinのマニュアル

Kotlin List<out T>タイプは、サイズ、取得などの読み取り専用操作を提供するインターフェイスです。 Javaと同様に、Collection<T>を継承し、次にIterable<T>を継承します。リストを変更するメソッドは、MutableList<T>インターフェイスによって追加されます。このパターンは、Set<out T>/MutableSet<T>およびMap<K, outV>/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の使用サイトの相違とは対照的です。

5
Kris Roofe