[KOTLIN] 제네릭 타입과 VARIANCE 한정자를 활용하라 (이펙티브 코틀린)

2022. 7. 10. 11:21·KOTLIN
728x90

제네릭 요약 참고

  • https://tgyun615.com/134?category=908821 
 

[JAVA] 제네릭

제네릭 클래스나 메소드에서 사용할 내부 데이터 타입을 컴파일 시에 미리 지정하는 방법 외부에서 사용자에 의해 타입이 지정되는 것을 의미 제네릭 장점 잘못된 타입이 들어올 수 있는 것을

tgyun615.com


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
'KOTLIN' 카테고리의 다른 글
  • [KOTLIN] 복잡한 객체를 생성하기 위한 DSL을 정의하라 (이펙티브 코틀린)
  • [KOTLIN] 일반적인 프로퍼티 패턴은 프로퍼티 위임으로 만들어라 (이펙티브 코틀린)
  • [KOTLIN] 타입 파라미터의 섀도잉을 피하라 (이펙티브 코틀린)
  • [KOTLIN] 연산자 오버로드를 할때는 의미에 맞게 사용
집한구석
집한구석
  • 집한구석
    tgyun615.info
  • 전체
    오늘
    어제
    • 카테고리 (183)
      • JAVA (38)
      • SPRING (15)
      • KOTLIN (23)
      • NETTY (1)
      • DEVOPS (3)
      • DOCKER (7)
      • KUBERNETES (2)
      • JAVASCRIPT (1)
      • SPLUNK (3)
      • ELK (7)
      • KAFKA (2)
      • GO (4)
      • ALGORITHM & DATA STRUCTURE (9)
      • IDE (5)
      • OS (16)
      • NETWORK (14)
      • GCP (2)
      • AWS (2)
      • DATABASE (10)
      • CLEANCODE (7)
      • OTHER (12)
  • 최근 글

  • 태그

    Spring
    IntelliJ
    ElasticSearch
    AWS
    이펙티브 코틀린
    이펙티브코틀린
    docker
    go
    코틀린
    클린코드
    JPA
    Elk
    cleancode
    SQL
    splunk
    자바
    java
    Kafka
    엘라스틱서치
    프로그래머스
  • 링크

    • github
    • linkedin
    • resume
  • hELLO· Designed By 정상우. v4.10.3
집한구석
[KOTLIN] 제네릭 타입과 VARIANCE 한정자를 활용하라 (이펙티브 코틀린)
상단으로

티스토리툴바