ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [코틀린] 제네릭 in / out
    개발/Kotlin 2023. 5. 24. 16:47
    재사용성을 위한 동일한 코드를 여러타입에 지원해주기 위해 제네릭 타입 선언시 <out T> , <in T>와 같은 접두어를 볼수있다.
    무엇을 위해  왜 사용되는지 알아 보려고 한다.

     

    불변성(Invariance) - <T>

    기본적으로 제네릭은 불변성을 가지고 있다. 제네릭 파라미터로 T를 받는다고 하면 T의 부모 및 자식과 비교해 보면 Type mismatch. 되며 타입이 정확히 일치하여야 한다. 안정성을 고려한 거라 볼 수 있다.

     

    class IPad : Apple() {}
    class IPhone : Apple() {}
    open class Apple {}

    위와 같은 상속 관계로 알아보면 

    fun main() {
        val iPads = arrayOf(IPad(), IPad())
        getAppleDevice(iPads) //error -> Type mismatch
    }
    
    
    fun getAppleDevice(device: Array<Apple>) {
        println("device size -> ${device.size}")
    }

    getAppleDevice에서 Array<Apple>을 받지만 Array<IPad>을 넘겨주고있다.
    부모 자식 관계 이지만 타입이 정확히 일치하지 않아 에러가 발생하게된다.  

    public class Array<T>

    Array의 제네릭 구현 형태를 보면 위와 같다.

     

     

     

    공변성(Covariance) - <out T>

    공변성은 A가 B의 서브타입이면, T<A>는 T<B>의 서브타입으로 볼 수 있다.

    안정성을 위해 위와 같은 타입은 제약되어있었지만 out 을 선언하여 허용 해줄 수 있다.

     

    위의 코드에서 Array를 List로 변경 해보면 알수있다.

    fun main() {
        val iPads = listOf(IPad(), IPad())
        getAppleDevice(iPads)
    }
    
    
    fun getAppleDevice(device: List<Apple>) {
        println("device size -> ${device.size}")
    }
    
    결과
    device size -> 2
    public interface List<out E> : Collection<E>

     

     

     

    반공변성(contravariance) - <in T>

    공변성과 반대되며 A가 B의 서브타입이면, T<B>는 T<A>의 서브타입이다.

    open class Apple : Device() {}
    open class Device {}

    Apple의 부모로 Device가 있다면

    fun main() {
        val devices = arrayOf(Device())
        getAppleDevice(devices)
    }
    
    
    fun getAppleDevice(device: Array<in Apple>) {
        println("device size -> ${device.size}")
    }

    in 을 사용하여 가능하다.

     

    out (Read only)  , in(Write only)

    out이나 in으로 받은 파라미터를 Read , Write 할 경우에도 차이점이 발생한다.
    우선 out의 경우 Read만 가능한데 out Apple 일 때 Apple의 하위 객체가 들어오게 됨으로 추측 가능하여 Read 할 수 있게 된다.
    반면 Write의 경우 종속관계가 없는 객체가 들어올 수 있으므로 Write 하지 못하게 된다.

     

    in의 경우 반대가 됨으로 상위 객체가 들어와 그 하위 객체를 Write 할  있게 된다.

    '개발 > Kotlin' 카테고리의 다른 글

    [코틀린] 변수 선업하기 (var, val)  (0) 2019.03.07

    댓글

Designed by Tistory.