지난 시간에 코틀린의 제네릭에 대해 학습했습니다
제네릭에 대해 궁금하시다면 아래의 링크↓↓↓
2020/05/17 - [Android] - [Android] 코틀린(Kotlin) 제네릭(Generic)
그런데 컴파일된 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 로 진행한다면
연쇄 호출이 안되게 됩니다)
이것으로 오늘의 학습을 마치도록 하겠습니다
그럼 이만-_-
'Android' 카테고리의 다른 글
[Android] 코틀린(Kotlin)과 자바(Java)의 상호운용 (0) | 2020.06.07 |
---|---|
[Android] 코틀린(Kotlin) 제네릭(Generic) (0) | 2020.05.17 |
[Android] 코틀린(Kotlin) sealed 클래스, 추상클래스, 인터페이스 (0) | 2020.05.08 |
[Android] 코틀린(Kotlin) 다른 타입의 클래스(Class) (0) | 2020.05.04 |
[Android] 코틀린(Kotlin) 클래스(Class)의 상속(Inheritance)와 타입(Type) (0) | 2020.05.04 |