728x90
제네릭 요약 참고
Variance 한정자 (out / in)
class Box<out T>
fun main(args: Array<String>) {
val box1: Box<Number> = Box<Int>() // OK!!
val box2: Box<Int> = Box<Number>() // Compile Error!!
}
----------------------------------------------
class Box<in T>
fun main(args: Array<String>) {
val box1: Box<Int> = Box<Number>() // OK!!
val box2: Box<Number> = Box<Int>() // Compile Error!!
}
- out은 타입 파라미터를 공변성(convariant)으로 만듬 (out T는 공변성)
- in은 타입 파라미터를 반공변성(contravariant)로 만듬 (in T는 반공변성)
- variance 한정자(out / in)이 선언이 없이 제네릭을 사용하면 무공변성으로 정의가 되어, 만들어지는 타입들이 서로 연관성이 없음
함수 타입
val intToDouble: (Int) -> Number = { it.toDouble() }
val numberAsText: (Number) -> Any = { it.toShort() }
val identity: (Number) -> Number = { it }
val numberToInt: (Number) -> Int = { it.toInt() }
val numberHash: (Any) -> Number = { it.hashCode() }
printProcessedNumber(intToDouble)
printProcessedNumber(numberAsText)
printProcessedNumber(identity)
printProcessedNumber(numberToInt)
printProcessedNumber(numberHash)
//(int) -> Any 타입의 함수는 위와 같은 함수로도 동작
fun printProcessedNumber(transition: (Int) -> Any) {
println(transition(42))
}
- 함수 타입은 파라미터 유형과 리턴타입에 따라서 관계가 달라짐
- 코틀린 함수 타입은 모든 파라미터타입은 반공변성, 모든리턴타입은 공변성임
- 함수 타입을 사용시 자동으로 variance 한정자가 사용됨
Variance 한정자 주의사항
- 코틀린은 public in 한정자 위치에 공변성 타입 파라미터 (out 한정자)가 오는 것을 금지함 (in 한정자 위치에 있을 경우, 공변성과 업캐스팅을 연결해서, 원하는 타입을 아무거나 전달할 수 있기 때문)
- 코틀린은 public out 한정자 위치에 반공변성 타입 파라미터가 오는 것을 금지함 (public out 위치는 암묵적으로 업캐스팅을 허용하나, 반공변성에 맞는 동작이 아님, 어떤타입이 들어오는지 확실하게 알 수가 없기 때문에)
Variance 한정자 위치
//선언부분에 사용
class Box<out T>(val value: T)
val box1: Box<String> = Box("Box")
val box2: Box<Any> = box1
//클래스와 인터페이스를 활용하는 부분에 사용
class Box<T>(val value: T)
val box1: Box<String> = Box("Box")
val box2: Box<out Any> = box1
- 한정자위치는 크게 선언부분과 클래스와 인터페이스를 활용하는 부분 두위치에서 사용이 가능함
- 선언 부분에서 사용하게 되면 클래스와 인터페이스 선언에 한정자가 적용이되며 모든곳에 영향을 끼침
- 활용하는 위치에서 적용하면 특정한 변수에만 한정자가 적용이 됨
- 활용하는 위치에 한정자를 적용할 경우 모든 인스턴스에 variance 한정자를 적용하면 안되고, 특정 인스턴스에만 적용해야 할 때, 위와같이 사용해야함
'KOTLIN' 카테고리의 다른 글
[KOTLIN] 복잡한 객체를 생성하기 위한 DSL을 정의하라 (이펙티브 코틀린) (0) | 2022.07.20 |
---|---|
[KOTLIN] 일반적인 프로퍼티 패턴은 프로퍼티 위임으로 만들어라 (이펙티브 코틀린) (0) | 2022.07.13 |
[KOTLIN] 타입 파라미터의 섀도잉을 피하라 (이펙티브 코틀린) (0) | 2022.07.10 |
[KOTLIN] 연산자 오버로드를 할때는 의미에 맞게 사용 (0) | 2022.07.03 |
[KOTLIN] NULLABLE UNIT 을 리턴하지 말라 (이펙티브코틀린) (0) | 2022.07.03 |