Kotlin/포스팅

코틀린 변성

짜집퍼박사(짜박) 2024. 1. 2. 21:31

코틀린에서 변성(variance)은 제네릭 타입 간의 서브 타이핑 관계를 설명하는데 사용되는 개념입니다. 변성은 주로 제네릭 클래스나 인터페이스를 설계할 때 타입 파라미터의 하위 타입 관계를 지정하는 데 활용됩니다. Kotlin에서는 세 가지 변성을 지원합니다: 공변성(Covariance), 반공변성(Contravariance), 무변성(Invariance).

 

1. 공변성 (Covariance)

공변성은 부모 타입의 제네릭 타입을 자식 타입으로 취급하는 것을 의미합니다. out 키워드를 사용하여 선언합니다. 이는 주로 읽기 연산에서 사용됩니다.

class Box<out T>(val value: T)

val box: Box<out Number> = Box(42)
val intBox: Box<out Int> = box  // 공변성

위의 예제에서 Box<out T>는 T가 공변적임을 나타냅니다. Box<out Number>는 Box<out Int>의 상위 타입이 되므로, Box<out Number> 타입에 Box<out Int>의 인스턴스를 할당할 수 있습니다.

 

2. 반공변성 (Contravariance)

반공변성은 부모 타입의 제네릭 타입을 자식 타입으로 취급하는 것을 의미합니다. in 키워드를 사용하여 선언합니다. 이는 주로 쓰기 연산에서 사용됩니다.

class Box<in T> {
    fun setValue(value: T) { /* ... */ }
}

val box: Box<in Int> = Box<Number>()
val anyBox: Box<in Any> = box  // 반공변성

위의 예제에서 Box<in T>는 T가 반공변적임을 나타냅니다. Box<in Int>는 Box<in Any>의 하위 타입이 되므로, Box<in Any> 타입에 Box<in Int>의 인스턴스를 할당할 수 있습니다.

 

3. 무변성 (Invariance)

무변성은 부모 타입과 자식 타입 간의 관계를 허용하지 않습니다. 즉, T와 U가 관련성이 없음을 나타냅니다. 기본적으로 제네릭 클래스나 인터페이스는 무변성입니다.

class Box<T>(val value: T)

val intBox: Box<Int> = Box(42)
// val numberBox: Box<Number> = intBox  // 오류: 무변성

위의 예제에서 Box<T>는 무변성입니다. Box<Int>는 Box<Number>의 상위 타입이나 하위 타입이 아니므로, 할당이 불가능합니다.

 

요약

- 공변성 (Covariance): out 키워드를 사용하며, 읽기 연산에서 사용됩니다.
- 반공변성 (Contravariance): in 키워드를 사용하며, 쓰기 연산에서 사용됩니다.
- 무변성 (Invariance): 기본적인 상태로, 부모 타입과 자식 타입 간의 관계를 허용하지 않습니다.

 

변성은 주로 제네릭 타입의 타입 파라미터가 사용되는 위치에서 지정됩니다. 함수의 매개변수에서 반공변성을 사용하거나, 반환 타입에서 공변성을 사용하는 등의 방식으로 제네릭 타입을 설계할 때 활용됩니다.

 

With ChatGPT

'Kotlin > 포스팅' 카테고리의 다른 글

코틀린 선언 지점 변성  (0) 2024.01.02
코틀린 변성의 생산자와 소비자 구분  (0) 2024.01.02
코틀린 타입 소거와 구체화  (0) 2024.01.02
코틀린 바운드와 제약  (0) 2024.01.02
코틀린 제네릭 선언  (0) 2024.01.02