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


85

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

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

List<out T>

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

답변:


58

이 서명으로 :

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>아닌 그 반대의 경우도 마찬가지.


1
나는 하나의 List<out T>선언문 에서 가장 중요한 점 out은 그것을 불변으로 만든다는 것입니다. 답변에서 그것을 언급하고 강조하는 것이 도움이 될 수 있습니다. 암시 적 캐스팅은 요점이 아니라 이것의 결과입니다 (List <Number>에 쓸 수 없으므로 List <Double>에 대한 참조로 사용하는 것이 안전합니다).
민스크

39
죄송합니다. 여전히 이해할 수 없습니다.
Akshay Taru

2
@minsk out부분은 List불변을 만드는 것이 아닙니다 . 인수가 필요하지 않으므로 메서드 List<out T>가있는 자체 인터페이스를 쉽게 만들 수 있습니다 clear().
Nick Lowery

이 주제는 코드에서 실제로 필요할 때까지 얻을 수있는 주제 중 하나입니다.
lasec0203

109
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

4

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의 사용 사이트 분산과 대조됩니다.


3

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

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

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

자바 출신이라면

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

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.