Gramática básica de Kotlin 13, Análisis de expresiones Lambba 4 (Gramática)

1. Sintaxis de expresión lambda

Mirando hacia atrás en el artículo anterior, necesitamos ejecutar una función en algún lugar. Solo conocemos el tipo de parámetro y el tipo de valor de retorno de esta función (el tipo de parámetro más el tipo de valor de retorno constituyen un tipo de datos especial en Kotlin: tipo de función), pero la función No nos importan las operaciones específicas, por lo que pasamos dinámicamente una función que cumple con las condiciones del tipo de parámetro y del tipo de valor de retorno, pero solo se pueden pasar objetos como parámetros, por lo que usamos dos puntos dobles o funciones anónimas para implementar una función. tipo objeto. Sin embargo, el código de estos dos métodos es relativamente engorroso. Para simplificar la cantidad de código y hacerlo conciso y claro, introdujimos la expresión Lambda, por lo que la esencia de la expresión Lambda es en realidad un objeto de tipo función. Nuestro El verdadero atractivo es tener un método establecido dinámicamente.

Ejemplo: ahora existe un método cuyo tipo de parámetro es un tipo de función

fun a(fb : (Int , String) -> String) {
    
    

}

Para llamar al método a, necesitamos pasar un objeto de tipo función.
Generalmente tenemos dos métodos:

  1. Puedes usar dos puntos:
fun b(p1 : Int , p2 : String) : String {
    
    
    return p2 + p1
}
a(::b)
  1. Utilice funciones anónimas
val b : (Int , String) -> String = fun(p1 : Int , p2 : String) : String {
    
    
    return p2 + p1
}
a(b)

Por supuesto, también puedes pasar la función anónima directamente:

a(fun(p1 : Int , p2 : String) : String {
    
    
    return p2 + p1
})

Puede ver que el método de la función anónima es demasiado engorroso, a continuación, presentamos expresiones Lambda para simplificarlo.

1.) El formato de la expresión Lambda es el siguiente:
{Parámetro 1: tipo de parámetro, Parámetro 2: tipo de parámetro,... -> Bloque de código de ejecución}

Nota: La última línea de expresión en el bloque de código de ejecución es el valor de retorno de la expresión Lambda
Esta expresión El tipo de retorno debe ser coherente con el tipo de valor de retorno declarado.

Entonces podemos usar la expresión Lambda para expresar la función anónima anterior como:

a({
    
     p1 : Int , p2 : String ->
    p2 + p1
})

2.) Cuando hayamos declarado explícitamente el tipo de función lambda, podemos omitir el tipo de parámetros en la lista de parámetros lambda,
por lo que se puede simplificar a:

a({
    
     p1 , p2 ->
    p2 + p1
})

3.) Cuando la expresión lambda se utiliza como último parámetro real de la llamada a la función, se puede colocar fuera del paréntesis,
por lo que se puede simplificar a:

a() {
    
     p1 , p2 ->
    p2 + p1
}

4.) Cuando lambda es el único parámetro real de la función, los corchetes vacíos de la función también se pueden eliminar,
por lo que se puede simplificar a:

a {
    
     p1 , p2 ->
    p2 + p1
}

Después de una simplificación continua, esta es la forma más común en nuestra vida diaria.
5.) Cuando solo hay un parámetro en la expresión lambda y se puede deducir el tipo de este parámetro, se generará el nombre del parámetro predeterminado para reemplazar este parámetro. En este momento, no es necesario declarar explícitamente el nombre. del parámetro, lo que significa que podemos omitirlo.
El ejemplo es el siguiente:

fun a(fb : (Int ) -> String) {
    
    

}
a{
    
    
    it.toString()
}

Nota: Cuando se anidan varias lambdas, es mejor declarar explícitamente los parámetros de cada expresión lambda; de lo contrario, será difícil determinar a qué valor se refiere, lo que afectará seriamente la legibilidad del código.
6.) Cuando utilice expresiones Lambda, puede utilizar un guión bajo (_) para indicar los parámetros no utilizados en el bloque de código de ejecución, lo que indica que este parámetro no se procesará.

a {
    
     _ , p2 ->
    p2
}

2. Conversión SAM

En el artículo anterior, también mencionamos el método de transferencia de funciones en Java usando interfaces. Kotlin también proporciona sintaxis lambda para interfaces, que es la conversión SAM:

  1. La conversión SAM solo funciona en interfaces, no en clases abstractas, incluso estas clases abstractas tienen solo un método abstracto.

  2. Debe ser una interfaz funcional, es decir, una interfaz declarada usando una interfaz divertida. Esta interfaz solo puede tener un método abstracto (obviamente, el objetivo final de la expresión lambda es tener una función dinámica).
    La conversión SAM es convertir lambda en función. explícitamente Funciones generadas a partir de instancias de interfaz

  3. Las interfaces funcionales y los tipos de funciones no son lo mismo . Esto es fácil de entender. Una es una interfaz y la otra es un tipo de datos. No se pueden mezclar.

Un ejemplo es el siguiente: Definimos una interfaz funcional

fun interface Click {
    
    
    fun click(a : Int) : String
}
fun a(c : Click) {
    
    
    c.click(1)
}

Sin usar lambda, por conveniencia, generalmente usamos expresiones de objeto para construir un objeto de una clase interna anónima y pasarlo.

a(object : Click {
    
    
    override fun click(a : Int) : String {
    
    
        return a.toString()
    }
})

Utilice lambda y la sintaxis no es diferente a la mencionada anteriormente.

a {
    
     a -> a.toString() }

Supongo que te gusta

Origin blog.csdn.net/weixin_43864176/article/details/123905674
Recomendado
Clasificación