[generics] 코 틀린의 통합 키워드는 어떻게 작동합니까?

나는 reified키워드 의 목적을 이해하려고 노력하고 있으며 , 그것은 generics에 대한 반영을 가능하게합니다 .

그러나 내가 그것을 떠나면 그것은 잘 작동합니다. 언제 이것이 실제적인 차이를 만들지 설명 할 사람이 있습니까?



답변

TL; DR : reified좋은 점

fun <T> myGenericFun(c: Class<T>) 

와 같은 일반 함수의 본문에서는 컴파일 타임에만 사용할 수 있지만 런타임에 지워 지기 때문에 myGenericFun유형에 액세스 할 수 없습니다 . 따라서 함수 본문에서 일반 유형을 일반 클래스로 사용하려면에 표시된대로 클래스를 매개 변수명시 적으로 전달 해야합니다 .TmyGenericFun

그래도 reifiedinline함수 를 작성하면 런타임에도 유형에 액세스 할 수 있으므로 추가 로 전달할 필요가 없습니다 . 마치 일반 클래스 인 것처럼 작업 할 수 있습니다 . 예를 들어 변수가의 인스턴스 인지 확인하고 싶을 때 쉽게 수행 할 수 있습니다 . TTClass<T>T TmyVar is T

이러한 유형 의 inline함수 는 다음과 같습니다.reifiedT

inline fun <reified T> myGenericFun()

어떻게 reified작동

함수reified 와 함께 만 사용할 수 있습니다 . 이러한 함수는 컴파일러 가 함수의 바이트 코드 를 함수가 사용되는 모든 위치에 복사합니다 (함수가 “인라인”되어 있습니다). Refined Type으로 인라인 함수를 호출하면 컴파일러는 형식 인수로 사용 된 실제 형식을 알고 해당 클래스를 직접 사용하도록 생성 된 바이트 코드를 수정합니다. 같은 따라서 호출 된다 (유형 인수가 있다면 ) 바이트 코드와 런타임에.inlinemyVar is TmyVar is StringString


얼마나 도움 reified이 될 수 있는지 보여주는 예를 살펴 보겠습니다 . 우리는 대한 확장 기능을 만들 String라고 toKotlinObject시도는 함수의 제네릭 형식에 의해 지정된 유형으로 일반 코 틀린 객체에 JSON 문자열을 변환 할 수 있음 T. com.fasterxml.jackson.module.kotlin이를 위해 사용할 수 있으며 첫 번째 접근 방식은 다음과 같습니다.

a) 형식이없는 첫 번째 방법

fun <T> String.toKotlinObject(): T {
      val mapper = jacksonObjectMapper()
                                                        //does not compile!
      return mapper.readValue(this, T::class.java)
}

그만큼 readValue 메소드는 구문 분석해야하는 유형을 사용합니다 JsonObject. Classtype 매개 변수 를 얻으려고 T하면 컴파일러에서 ” ‘T’를 고정 형식 매개 변수로 사용할 수 없습니다. 대신 클래스를 사용하십시오.”

b) 명시 적 Class매개 변수를 사용한 해결 방법

fun <T: Any> String.toKotlinObject(c: KClass<T>): T {
    val mapper = jacksonObjectMapper()
    return mapper.readValue(this, c.java)
}

해결 방법으로 Class of T를 메서드 매개 변수로 만들 수 있으며이 매개 변수는에 대한 인수로 사용됩니다 readValue. 이것은 작동하며 일반적인 Java 코드에서 일반적인 패턴입니다. 다음과 같이 호출 할 수 있습니다.

data class MyJsonType(val name: String)

val json = """{"name":"example"}"""
json.toKotlinObject(MyJsonType::class)

c) 코 틀린 방식 : reified

유형 매개 변수 inline와 함께 함수 사용reifiedT 다르게 구현할 수 있습니다.

inline fun <reified T: Any> String.toKotlinObject(): T {
    val mapper = jacksonObjectMapper()
    return mapper.readValue(this, T::class.java)
}

테이크 할 필요가 없습니다 ClassT추가는,T 일반 수업처럼 사용할 수 있습니다. 클라이언트의 경우 코드는 다음과 같습니다.

json.toKotlinObject<MyJsonType>()

중요 사항 : Java를 사용한 작업

reified유형이 인라인 된 함수 는 Java 코드 에서 호출 할 수 없습니다 .


답변

단순한

* 컴파일 시점에 사용 권한을 부여하는 것입니다 (함수 내부의 T에 액세스하기 위해)

예 :

 inline fun <reified T:Any>  String.convertToObject(): T{

    val gson = Gson()

    return gson.fromJson(this,T::class.java)

}

같은 사용 :

val jsonStringResponse = "{"name":"bruno" , "age":"14" , "world":"mars"}"
val userObject = jsonStringResponse.convertToObject<User>()
  println(user.name)


답변