[generics] Kotlin의 키워드는 무엇입니까?

이해할 수없고 kotlin에서 out 키워드 의 의미를 찾을 수 없습니다 .

여기에서 예를 확인할 수 있습니다.

List<out T>

누구든지 이것의 의미를 설명 할 수 있다면. 정말 감사하겠습니다.



답변

이 서명으로 :

List<out T>

다음과 같이 할 수 있습니다.

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

이는 T공변 임을 의미합니다 .

매개 변수 유형의 경우 T 클래스의 C가 선언 아웃 , C <베이스> 안전하게 할 수 있습니다 슈퍼C <유도> .

이것은 in 과 대조 됩니다 . 예 :

Comparable<in T>

다음과 같이 할 수 있습니다.

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

이는 T반 변성 을 의미합니다 .

매개 변수 유형의 경우 T 클래스의 C이 선언 에서 , C <유도> 안전하게 할 수 있습니다 슈퍼C <자료> .

기억하는 또 다른 방법 :

소비자 , 생산자 .

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

예를 들어 Kotlin에서는 다음과 같은 작업을 수행 할 수 있습니다.

 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가 out으로 선언되면의 멤버의 out-position에서만 발생할 수 C있지만 반환되는 C<Base>경우 안전하게의 상위 유형이 될 수 있습니다 C<Derived>.

“영리한 단어”에서 그들은 클래스 C가 매개 변수 T에서 T공변 적이거나 공변 유형 매개 변수 라고 말합니다 . C를의 소비자가 아니라 T의 생산자로 생각할 수 있습니다 T. out 수정자는 분산 주석이라고하며 유형 매개 변수 선언 사이트에서 제공되므로 선언 사이트 분산에 대해 이야기합니다. 이것은 유형 사용의 와일드 카드가 유형을 공변하게 만드는 Java의 사용 사이트 분산과 대조됩니다.


답변

다음과 같이 기억하십시오.

in“for in put”-당신은 그것에 무언가를 넣어 (쓰기) 원합니다 (그래서 그것은 “소비자”입니다)

out“for out put”입니다-당신은 그것에서 뭔가를 꺼내고 싶어합니다 (그래서 그것은 “프로듀서”입니다)

자바 출신이라면

<in T>입력을위한 것이므로 <? super T>(소비자)

<out T>출력용이므로 <? extends T>(제작자)


답변