Hola, me llamo Miguel y esta vez les traigo un artículo.
Resuelva la sobrecarga lambda
y supere el borrado de tipo
Las funciones en línea reemplazan la llamada a la función con el cuerpo de la función en sí. Por lo tanto, se guarda la sobrecarga de la llamada a la función.
La sobrecarga es mucho mayor cuando la función es una función de orden superior, es decir, contiene una lambda
como parámetro de función. Las funciones en línea vienen al rescate e integran la función llamada así como el cuerpo lambda
.
Los parámetros de tipo reificado junto con la palabra clave en línea en Kotlin se utilizan en el contexto de los genéricos.
En tiempo de ejecución, se borra cualquier información sobre los argumentos de tipo reales utilizados por las instancias de clase genérica, lo que significa que no podemos acceder al tipo genérico <T>
durante el tiempo de ejecución.
Type Erasure
también existe en Java. Sin embargo, Kotlin proporciona una forma de acceder al parámetro de tipo durante el tiempo de ejecución usando reified
con inline
.
inline fun execute() { print("Hello") }
El código de bytes de Kotlin descompilado (Tools-> Kotlin-> Show Kotlin Bytecode-> Decompile
) para la llamada a la función execute ()
es como se muestra a continuación:
int $i$f$execute = false; String var4 = "Hello"; boolean var5 = false; System.out.print(var4);
Para elaborar, utilizando la palabra clave en línea, el compilador reemplaza la llamada a la función en línea con el cuerpo de la función.
Las funciones de orden superior en Kotlin se convierten en objetos de clase, implementando la función lambda, en el momento de la compilación y se realiza una llamada virtual a la función cuando se invoca la función lambda.
Todo esto es una operación costosa e introduce una sobrecarga de tiempo de ejecución debido a las asignaciones de memoria para la clase y el objeto y la llamada de función virtual.
fun execute(myfun : () -> Unit) { myfun() }
El código de bytes Kotlin descompilado para la función anterior es:
public final void execute(@NotNull Function0 myfun) { Intrinsics.checkParameterIsNotNull(myfun, "myfun"); myfun.invoke(); }
Aquí, podemos ver que se está llamando a la función invoke ()
en el objeto myfun
creado. Funciona como se muestra a continuación en Java:
execute(new Function0() { @Override public void invoke() { print(“Hello”); } });
La sobrecarga debida a las asignaciones de memoria sería mayor si hay varias lambdas
altas.
Podemos superar esta sobrecarga de tiempo de ejecución utilizando la palabra clave en línea como se muestra a continuación:
inline fun execute(myfun : () -> Unit) { myfun() }
Para la llamada a la función de ejecución,
execute { print("Hello") }
El código de bytes
Kotlin descompilado para la llamada a la función execute ()
ahora se convierte en como se muestra a continuación:
int $i$f$execute = false; int var4 = false; String var5 = "Hello"; boolean var6 = false; System.out.print(var5);
Aquí, podemos ver que la llamada a la función de ejecución es reemplazada por el código en el cuerpo de la función de ejecución.
Parámetros del tipo Reificado
Como ya se ha dicho, toda información sobre los argumentos de tipo real utilizados por las instancias de clase genérica se borra y no está disponible en tiempo de ejecución.
A veces, necesitamos acceder al parámetro de tipo genérico en tiempo de ejecución. Esto se puede hacer utilizando una palabra clave en línea combinada con un modificador reificado con el parámetro type
.
Para utilizar los parámetros de tipo reificado, una función tiene que ser una función en línea.
Véase el ejemplo que figura a continuación como referencia.
inline fun <reified T> execute(input: T) { if(T::class == String::class) { println((input as String).length) } else if(T::class == Int::class){ println(input) } }
Gracias por leer este artículo.
Añadir comentario