En este tutorial aprenderás sobre la declaración de funciones de orden superior en Kotlin. Verás ejemplos para pasar una función como argumento de otra y para retornar una función de otra función.
Función De Orden Superior
Una función de orden superior, es una función que puede recibir como argumento una o más funciones y/o retornar una función como resultado.
// Pasar función como argumento de otra función
fun recibirFuncion(parametro1: (String) -> Int, parametro2: Double) {
// Invocar instancia del tipo función
val numero: Int = parametro1("Arg")
print(numero)
}
// Retornar función desde otra función
fun retornarFuncion(parametro1: Int): () -> Unit {
// el retorno es una función lambda
return { println(parametro1) }
}
Esto es posible gracias a los tipos función que Kotlin incluye en su gramática.
Tomar Funciones Como Argumentos
Para recibir argumentos en una función, agrega a la firma uno o varios parámetros de tipo función.
El fin es ejecutar la función entrante, realizarle una llamada y hacer el uso correspondiente de su resultado.
Por ejemplo:
Supongamos que estamos generando el código para un juego de cartas roguelike y necesitamos poner en juego una carta que causa un efecto, basado en el costo de otra aleatoria en el mazo.
// Función de orden superior
fun playEffectCard(cardCost1: Int, cardCost2: Int, onSuccess: () -> Unit) {
if (cardCost1 > cardCost2) {
onSuccess()
} else {
println("Sin efectos")
}
}
fun main() {
val warriorCardCost = 1
val randomDeckCardCost = 4
playEffectCard(warriorCardCost, randomDeckCardCost) { print("Aumentar armadura por 10") }
}
Salida:
Sin efectos
En el código anterior creamos una función de orden superior, que recibe los costos (cardCost1
y cardCost2
) de las cartas que serán comparados.
El tercer parámetro onSuccess
es una función de tipo () -> Unit
, que ejecutará el efecto de la carta, si la comparación fue exitosa.
Al llamar a playEffectCard()
en main()
, pasamos en el tercer argumento un lambda que imprime el efecto causado.
Debido a que warriorCostCard
no es mayor a randomDeckCost
, la salida será la no aplicación de efectos.
Pasar Referencia De Función
La función lambda que pasamos como argumento en la función de orden superior anterior, puede ser reescrito como una referencia de función si así lo deseas:
fun increaseArmor() {
print("Aumentar armadura por 10")
}
fun main() {
val warriorCardCost = 1
val randomDeckCardCost = 4
playEffectCard(warriorCardCost, randomDeckCardCost, ::increaseArmor)
}
Retornar Funciones Desde Funciones
Retornar un tipo función desde una función de orden superior tiene la misma sintaxis de un retorno regular.
Defines el tipo en la firma de la función y en el bloque de código de la misma, usas la expresión return
para especificar el literal de función o referencia que será devuelto como valor.
Por ejemplo:
Convertir de metros a centímetros, pulgadas, pies y yardas.
import Dimension.*
enum class Dimension {
CM, INCH, FOOT, YARD
}
fun getConversion(dimension: Dimension): (Double) -> Double {
return when (dimension) {
CM -> { mts -> mts * 100 }
INCH -> { mts -> mts * 39.37 }
FOOT -> { mts -> mts * 3.281 }
YARD -> { mts -> mts * 1.094 }
}
}
fun main() {
val meters = 20.0
print(getConversion(FOOT)(meters))
}
Salida:
65.62
Solución:
El código propuesto provee una clase enum para determinar los tipos de dimensiones que deseamos (CM
, INCH
, FOOT
y YARD
).
Luego creamos una función de orden superior que recibe una instancia de Dimension
y basado en ella usamos una expresión when para procesar cada constante.
Cada constante arroja como valor una función lambda del tipo (Double)->Double
. Lo que significa que toma como parámetro la cantidad en metros y lo mapea a una multiplicación por el factor asociado al sistema de conversión.
Finalmente en main()
, declaramos una variable con 20 metros. Luego llamamos a la función getConversion()
, especificando que queremos convertir a pies la cantidad.
Como el retorno es una función, al final de los paréntesis podemos añadir otros paréntesis para llamar al cálculo.
Ú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!