En este tutorial discutiremos sobre los tipos función en Kotlin (en inglés function types), con el fin de entender como las funciones pueden ser pasadas como argumentos y ser retornadas en expresiones.
Definición De Tipos Función En Kotlin
El tipo función (FT) es el tipo de una variable o parámetro, a los cuales se les ha asignado o puede asignar una función.
O el tipo para un argumento o resultado de retorno de una función de orden superior.
Esta capacidad de usar a las funciones como valores es posible gracias a la interfaz kotlin.Function
de Kotlin.
Sintaxis De Tipos Función
La declaración de un tipo función en su forma base, se compone de los tipos de los argumentos que toma en paréntesis, el operador ->
y el tipo que retorna.
FT(A1, … , An) → R
Por ejemplo, un tipo función cuyo par de argumentos String
corresponde un resultado String
:
(String, String) -> String
Uno que toma un entero como parámetro pero no tiene retorno particular sería:
(Int) -> Unit
O si existe un tipo función sin parámetros que retorna un Double
:
() -> Double
Almacenar Lambda En Variable
Como viste al inicio, el tipo función nos abre un nuevo abanico de posibilidades. Y una de ellas es el almacenamiento de instancias tipo función en variables.
Como caso particular, veamos instancias escritas como funciones lambda .
Por ejemplo, si deseamos juntar el nombre y apellido de un cliente para un formato simple, podemos almacenar la lambda así:
val nombreConFormato = { nombre: String, apellido: String -> "$nombre $apellido"} }
La declaración anterior omite el tipo, ya que el compilador lo puede inferir, pero explícitamente se vería así.
val nombreConFormato: (String, String) -> String= { nombre: String, apellido: String -> "$nombre $apellido"} }
Debido a que la función lambda usa una lista de dos parámetros String
y retorna la concatenación de ambos, el tipo función es (String, String) -> String
.
Invocar Una Instancia De Tipo Función
Puedes llamar la lambda de una variable de tipo función como una función normal o usar el operador invoke()
.
Por ejemplo, ejecutemos la función lambda anterior.
fun main() {
// Almacenar lambda en variable
val nombreCompleto = { nombre: String, apellido: String -> "$nombre $apellido" }
println(nombreCompleto("Laura", "Min"))
println(nombreCompleto.invoke("Carlos", "Xhan"))
}
La salida será:
Laura Min
Carlos Xhan
Usar lambdas almacenados te será de utilidad cuando desees posponer el resultado a tu conveniencia, componer lambdas y por supuesto en funciones de orden superior.
Tipos Función Anulables
Los tipos función también pueden ser anulables. La sintaxis para su declaración es recubrir el tipo y agregar ?
.
(()->Int)? // Agrega ? al final
Por ejemplo, almacenemos una función lambda en la variable getStars
, que dependa de la condición de si el usuario pagó por estrellas. Si es así, calculamos la cantidad, de lo contrario no se asignarán sentencias ejecutables.
fun main() {
val payment = 10
val getStars: ((Int) -> Int)? =
if (payment > 0) { cost: Int -> cost * 10 } else null
// Invocar instancia de tipo función
if (getStars != null) {
print("Estrellas recibidas:${getStars(10)}")
}
}
Al correr la aplicación tendrás:
Estrellas recibidas:100
Pero si cambias el valor de payment
a 0
no se ejecutará nada.
Obviamente también puedes usar el operador de acceso seguro como cualquier tipo anulable. Llama a invoke()
para habilitar el uso del operador:
getStars?.invoke(10)
Únete Al Discord De Develou
Si tienes problemas con el código de este tutorial, preguntas, recomendaciones o solo deseas discutir sobre desarrollo Android conmigo y otros desarrolladores, únete a la comunidad de Discord de Develou y siéntete libre de participar como gustes. ¡Te espero!