Android

[Android] 코틀린(Kotlin)의 실체화(Reification)와 확장(Extension)

구루싸 2020. 6. 7. 11:12
반응형
SMALL

지난 시간에 코틀린의 제네릭에 대해 학습했습니다

제네릭에 대해 궁금하시다면 아래의 링크↓

2020/05/17 - [Android] - [Android] 코틀린(Kotlin) 제네릭(Generic)

[Android] 코틀린(Kotlin) 제네릭(Generic)

지난 시간까지 여러 종류의 클래스와 인터페이스에 대해 학습하였습니다 오늘의 학습 주제는 코틀린의 제네릭(generic)에 대해 알아보겠습니다 제네릭은 클래스와 인터페이스의 매개변수 또는 �

yssa.tistory.com

그런데 컴파일된 JVM 바이트코드에는

제네릭 타입 매개변수의 정보가
수록되지 않고 소거됩니다

따라서 프로그램 런타임 시에
아래와 같이 타입과 관련한 문제가
발생할 수 있습니다



   (원인) List<Int<와 List<String> 모두 JVM 바이트코드에는 원시 타입인 List로 처리함

위와 같은 문제를 해결하기 위해
코틀린은 제네릭 타입 매개변수의
실체화(Reification)을 지원하고

reified 키워드를 사용합니다
실체화는 결국 제네릭 타입을
명시한다는 것을 의미합니다

inline fun <reified T> randomOrBackupLoot(backupLoot: () -> T): T {
    val items = listOf(Coin(14), Fedora("Ordinary fedora", 150))
    val randomLoot: Loot = items.shuffled().first()
    return if (randomLoot is T) {
        randomLoot
    } else {
        backupLoot()
    }
}
fun main(args: Array<String>) {
    randomOrBackupLoot {
        Fedora("Alternative fedora", 15)
    }.run {
        println(name)
    }
}

위의 코드에서 main 함수 내의 randomOrBackupLoot부분은

inline 키워드를 지정했기 때문에
randomOrBackupLoot 함수 몸체의

모든 코드로 대체되어 삽입되고
(inline 키워드에 대해서는 학습하였습니다)

reified로 인해 실제로 컴파일된 바이트코드는

T 대신에 Fedora가 삽입됩니다

따라서 타입 검사를 런타임 시에
할 수 없는 문제를 해결할 수 있게됩니다

다음으로 코틀린의
확장(Extension)에 대해 알아보겠습니다

확장은 기존 타입의 정의를 직접 변경하지 않고

새로운 기능을 추가할 수 있게 해주는데요

사용자 정의 타입(우리가 만든 타입)과
표준 라이브러리의 타입에도 사용가능합니다

val String.numVowels
    get() = count { "aeiouy".contains(it) }
fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount)
fun <T> T.easyPrint(): T {
    println(this)
    return this
}
infix fun String?.printWithDefault(default: String) = print(this ?: default)
fun main(args: Array<String>) {
    "Came out of that building".easyPrint().addEnthusiasm().easyPrint()
    42.easyPrint()
    "How many vowels?".numVowels.easyPrint()
    
    val nullableString: String? = null
    nullableString printWithDefault "Basic String"
}

위의 코드에서 조금 생소한 infix 키워드가 보이는데요

infix 키워드는 하나의 인자를 갖는

확장 함수와 클래스 함수 모두에 사용할 수 있는데

함수 호출 문법을 간결하게 하는 역할을 합니다
이렇게 함수에 infix 키워드를 지정한 것을

중위 함수(infix function)라고 하며

.(dot) 과 괄호를 생략하게 해줌으로써
함수 호출 문법을 간결하게 합니다

easyPrint() 함수는 제네릭 타입 매개변수 T를
이용하여 타입에 의해 연쇄 호출이 막히는
현상을 가능하도록 하였습니다
(만약 T가 아닌 Any 로 진행한다면
연쇄 호출이 안되게 됩니다)

이것으로 오늘의 학습을 마치도록 하겠습니다

그럼 이만-_-

반응형
LIST