Funciones en línea de Kotlin

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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *