Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

끄적끄적

구체화된 타입 파라미터 'reified' 본문

Kotlin

구체화된 타입 파라미터 'reified'

kimii 2021. 10. 20. 17:16

JVM에서는 제네릭을 사용할 때 Java의 타입 이레이저때문에 컴파일 타임에 타입 정보가 사라진다.

 

코틀린은 구체화된 타입 파라미터(Reified Type Parameter)를 통해서 이러한 문제를 해결할 수 있다.

 


abstract class Person(val name: String)
class Man(name: String) : Human(name)
class Woman(name: String) : Human(name)

위와 같은 클래스들이 있다고 가정을 했을 때, 아래와 같은 리스트를 만들 수 있다.

val people: List<Person> = 
	listOf(Man("Homer Simpson"), Woman("Marge Simpson"), Man("Bart Simpson"), Woman("Lisa Simpson"), Woman("Maggie Simpson"))

 

위의 리스트에서 특정 타입의 첫 번째 인스턴스를 찾아야 할 때 아래와 같이 작성할 수 있다.

fun <T> findFirst(people: List<Person>, ofClass: Class<T>): T {
    val selected = people.filter { person -> ofClass.isInstance(person) }
    if(selected.size == 0)
    	throw RuntimeException("Not Found")
    
    return ofClass.cast(selected[0]
}

위의 스타일은, 자바에서 일반적으로 작성하는 스타일이다. 이러한 경우에는 바이트 코드로 컴파일되면서 타입 T가 지워지기 때문에 findFirst 함수 내에서 

 

person is T
selected[0] as T

와 같은 연산자를 사용할 수 없다. 따라서 위 예제에서는 ofClass: Class<T>를 사용하였다. 이러한 방법은, 함수가 호출될 때마다 타입 정보를 추가적으로 함수에 전달해줘야하고, 받는 쪽과 호출하는 쪽에서 나쁜 코드를 만듦과 동시에 오류가 나는 경우가 종종 있다.

 

코틀린엔 refied 타입 파라미터가 있다.

타입 이레이저의 한계를 다루기 위해 코틀린은 파라미터 타입이 reified라고 마크되어있고, inline으로 선언된 함수라면

파라미터 타입을 사용할 수 있도록 권한을 준다.

reified 

 

inline 함수는 컴파일 시점에 확정되어 함수 호출 시 오버헤드가 없는 함수이다.

 

이를 토대로 findFirst 함수를 리팩토링하면 다음과 같다.

inline fun <reified T> findFirst(people: List<Person>) : T {
    val selected = people.filter { person -> person is T }
    if(selected.size == 0)
    	throw RuntimeException("Not found")
    
    return selected[0] as T
}

 

이처럼 제네릭을 사용할 때에 타입 캐스팅이 필요하다면, `inline` 함수와 `reified` 파라미터를 사용하여 컴파일 타임에 타입 안전성을 강화할 수 있다.

'Kotlin' 카테고리의 다른 글

탑 레벨 함수 vs 싱글톤  (0) 2021.10.20
Scope Function(with, run, T.with, T.run, let, also, apply)  (0) 2021.09.08
Comments