Estoy tratando de entender el propósito de la reified
palabra clave, aparentemente nos permite reflexionar sobre los genéricos .
Sin embargo, cuando lo dejo fuera, funciona igual de bien. ¿Alguien quiere explicar cuándo esto hace una diferencia real ?
generics
kotlin
kotlin-reified-type-parameters
hl3mukkel
fuente
fuente
Respuestas:
TL; DR: ¿Qué es
reified
bueno paraEn el cuerpo de una función genérica como
myGenericFun
, no puede acceder al tipoT
porque solo está disponible en tiempo de compilación pero se borra en tiempo de ejecución. Por lo tanto, si desea utilizar el tipo genérico como una clase normal en el cuerpo de la función, debe pasar explícitamente la clase como parámetro como se muestra enmyGenericFun
.Si creas un
inline
función con una reifiedT
,T
se puede acceder al tipo de incluso en tiempo de ejecución y, por lo tanto, no necesita pasarloClass<T>
adicionalmente. Puede trabajar conT
como si fuera una clase normal, por ejemplo, es posible que desee comprobar si una variable es un ejemplo deT
que se puede hacer fácilmente a continuación:myVar is T
.Tal
inline
función conreified
tipo seT
ve de la siguiente manera:Como
reified
funcionaSolo se puede usar
reified
en combinación con unainline
función . Tal función hace que el compilador copie el código de bytes de la función en cada lugar donde se está utilizando la función (la función está "en línea"). Cuando llama a una función en línea con tipo reified, el compilador conoce el tipo real utilizado como argumento de tipo y modifica el bytecode generado para usar la clase correspondiente directamente. Por lo tanto, las llamadas semyVar is T
convierten enmyVar is String
(si el argumento de tipo fueraString
) en el código de bytes y en tiempo de ejecución.Ejemplo
Echemos un vistazo a un ejemplo que muestra cuán útil
reified
puede ser. Queremos crear una función de extensión paraString
llamadastoKotlinObject
que intente convertir una cadena JSON en un objeto Kotlin simple con un tipo especificado por el tipo genérico de la funciónT
. Podemos usarcom.fasterxml.jackson.module.kotlin
esto y el primer enfoque es el siguiente:a) Primer enfoque sin tipo reificado
El
readValue
método toma un tipo que se supone que debe analizarJsonObject
. Si tratamos de obtener elClass
parámetro typeT
, el compilador se queja: "No se puede usar 'T' como parámetro de tipo reified. En su lugar, use una clase".b) Solución alternativa con explícito
Class
parámetroComo solución alternativa, la
Class
deT
puede hacerse un parámetro de método, que luego se usa como un argumento areadValue
. Esto funciona y es un patrón común en el código genérico de Java. Se puede llamar de la siguiente manera:c) La forma de Kotlin:
reified
Usar una
inline
función conreified
parámetro de tipoT
hace posible implementar la función de manera diferente:No hay necesidad de tomar el
Class
deT
adicionalmente,T
se puede utilizar como si se tratara de una clase ordinaria. Para el cliente, el código se ve así:Nota importante: trabajar con Java
Una función en línea con
reified
tipo no se puede llamar desde el código Java .fuente
SENCILLO
* reified es dar permiso para usar en tiempo de compilación (para acceder a T dentro de la función)
p.ej:
usando como:
fuente