En Kotlin, las funciones de orden superior o las expresiones lambda, todas almacenadas como un objeto , por lo que la asignación de memoria, tanto para los objetos de función como para las clases, y las llamadas virtuales pueden generar una sobrecarga en el tiempo de ejecución. A veces, podemos eliminar la sobrecarga de memoria insertando la expresión lambda. Para reducir la sobrecarga de memoria de tales funciones de orden superior o expresiones lambda, podemos usar la palabra clave en línea que, en última instancia, solicita al compilador que no asigne memoria y simplemente copie el código en línea de esa función en el lugar de la llamada.
Ejemplo:
Kotlin
fun higherfunc( str : String, mycall :(String)-> Unit) { // inovkes the print() by passing the string str mycall(str) } // main function fun main(args: Array<String>) { print("GeeskforGeeks: ") higherfunc("A Computer Science portal for Geeks",::print) }
Código de bytes: al igual que Java, Kotlin también es un lenguaje independiente de la plataforma, por lo que se convierte primero en el código de bytes. Podemos obtener el bytecode como Tools -> Kotlin -> Show Kotlin Bytecode . Luego, descompile para obtener este código de bytes.
En el código de bytes anterior, la parte principal en la que centrarse es:
mycall.invoke(str)
mycall invoca la función de impresión pasando la string como parámetro. Al invocar print(), crearía una llamada adicional y aumentaría la sobrecarga de memoria.
funciona como
mycall(new Function() { @Override public void invoke() { //println statement is called here. } });
Si llamamos a una gran cantidad de funciones como parámetros, cada una de ellas se sumaría al recuento del método, entonces habría un gran impacto en la memoria y el rendimiento.
¿Qué palabra clave en línea hará en el programa anterior?
Kotlin
inline fun higherfunc( str : String, mycall :(String)-> Unit){ // inovkes the print() by passing the string str mycall(str) } // main function fun main(args: Array<String>) { print("GeeskforGeeks: ") higherfunc("A Computer Science portal for Geeks",::print) }
código de bytes:
Con la ayuda de la palabra clave inline , la expresión lambda println se copia en la función principal en forma de System.out.println y no se requieren más llamadas.
Flujo de control no local
En Kotlin, si queremos regresar de una expresión lambda, el compilador de Kotlin no nos permite hacerlo. Con la ayuda de la palabra clave en línea, podemos regresar desde la propia expresión lambda y salir de la función en la que se llama a la función en línea.
Programa Kotlin de uso de Return en Lambda Expression:
Kotlin
var lambda = { println("Lambda expression") return } // normally lambda expression does not allow return // statement, so gives compile time error fun main(args: Array<String>) { lambda() }
Producción:
Error:(4, 5) Kotlin: 'return' is not allowed here
Normalmente no permite volver de lambda y da error.
Kotlin
var lambda1 = { println("Lambda expression")} fun main(args: Array<String>) { lambda1() }
Producción:
Lambda expression
Normalmente sin que funcione bien e imprima la declaración.
Programa de Kotlin para usar Return en Lambda mientras se pasa como un argumento a la función en línea:
Kotlin
fun main(args: Array<String>){ println("Main function starts") inlinedFunc({ println("Lambda expression 1") return }, // inlined function allow return // statement in lambda expression // so, does not give compile time error { println("Lambda expression 2")} ) println("Main function ends") } // inlined function inline fun inlinedFunc( lmbd1: () -> Unit, lmbd2: () -> Unit ) { lmbd1() lmbd2() }
Producción:
Main function starts Lambda expression 1
Explicación: aquí pasamos dos expresiones lambda como argumentos a la función inlinedFunc() . Mientras llamamos a la función en línea desde la función principal, pasamos ambas a sus argumentos. En la función en línea, lmbd1() invocó la primera expresión y la palabra clave de retorno fuerza la expresión lambda y la función principal desde donde se llama para salir.
palabra clave cruzada
En el programa anterior, return in lambda sale de la función en línea, así como de su función envolvente. Entonces, para dejar de regresar de la expresión lambda, podemos marcarla usando la línea cruzada. Lanzará un error del compilador si ve alguna declaración de retorno en la expresión Lambda.
Ejemplo:
Kotlin
fun main(args: Array<String>){ println("Main function starts") inlinedfunc({ println("Lambda expression 1") return }, // It gives compiler error { println("Lambda expression 2")} ) println("Main function ends") } inline fun inlinedfunc( crossinline lmbd1: () -> Unit, lmbd2: () -> Unit ) { lmbd1() lmbd2() }
Producción:
Error:(6, 9) Kotlin: 'return' is not allowed here
Sin línea
En Kotlin, si queremos que solo algunas de las lambdas pasadas a una función en línea estén en línea, podemos marcar algunos de los parámetros de la función con el modificador noinline.
Kotlin
fun main(args: Array<String>){ println("Main function starts") inlinedFunc({ println("Lambda expression 1") return }, // It does not compiler time error { println("Lambda expression 2") return } ) // It gives compiler error println("Main function ends") } inline fun inlinedFunc( lmbd1: () -> Unit, noinline lmbd2: () -> Unit ) { lmbd1() lmbd2() }
Producción:
Error:(11, 13) Kotlin: 'return' is not allowed here
Parámetros de tipo cosificados
A veces necesitamos acceder al tipo de parámetro pasado durante la llamada. Simplemente tenemos que pasar el parámetro en el momento de llamar a la función y podemos recuperar el tipo del parámetro usando un modificador cosificado.
Kotlin
fun main(args: Array<String>) { genericFunc<String>() } inline fun <reified T> genericFunc() { print(T::class) }
Producción:
class kotlin.String
Propiedades en línea
La función en línea copia el código en el lugar de llamada, de manera similar, la palabra clave en línea copia los métodos de acceso de propiedades en línea al lugar de llamada. El modificador en línea se puede usar en elementos de acceso de propiedades que no tienen un campo de respaldo.
Kotlin
fun main(args: Array<String>) { print(flag) } fun foo(i: Int ): Int{ var a = i return a } inline var flag : Boolean get() = foo(10 ) == 10 set(flag) {flag}
Producción:
true
Publicación traducida automáticamente
Artículo escrito por Praveenruhil y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA