Funciones infix
Una de las metas que persigue Kotlin es procurar un código lo más legible y conciso posible, y con ese objetivo soporta la anotación de las funciones con la palabra reservada infix precediendo al nombre de la función. Esto permite, a grandes rasgos, invocar esa función de una manera más cercana al lenguaje natural sin necesidad de escribir el punto y los paréntesis, como si se tratara de un simple operador aritmético.
Se puede ver más claro en el siguiente ejemplo donde tenemos una función de extensión con la anotación infix, y dos posibles maneras de llamar a esa función:
infix fun Int.multiplicarPor(x: Int): Int { ... } // llamada común a la función 4.multiplicarPor(2) // llamada a la función usando la anotación infix 4 multiplicarPor 2
Por supuesto, para utilizar esta manera de llamar a una función (omitiendo el punto y los paréntesis), ésta debe estar marcada con infix en su declaración. Además hay que tener en cuenta que la anotación infix solo se puede aplicar a funciones miembro de una clase y a funciones de extensión, y siempre a funciones con un solo parámetro (además este parámetro no debe aceptar un número variable de argumentos ni tener un valor predeterminado).
Desarrollando el código anterior:
infix fun Int.multiplicarPor(factor: Int) = this * factor fun main() { val producto = 20 multiplicarPor 5 // es igual a 20.multiplicarPor(5) println("20 x 5 = $producto") }
En definitiva, la anotación infix permite llamar fácilmente a una función miembro o a una función de extensión, escribiendo primero el objeto sobre el que se aplica la función (receptor), luego el nombre de la función y se termina con el argumento que se pasa a la función (parámetro).
Un ejemplo de una función de clase con anotación infix:
class Alumno { var nota = 0.0 // función con anotación infix infix fun sumarPracticas(notaPracticas: Double) { this.nota = nota + notaPracticas } } fun main() { val alumno = Alumno() alumno.nota = 4.5 // llamada a la función usando la anotación infix alumno sumarPracticas 5.00 print(alumno.nota) // 9.5 }
Y así conseguimos un código más expresivo y claro, simple y directo.
Por otra parte, hay que tener en cuenta que para invocar una función infix siempre y en todos los casos se requiere explicitar tanto el receptor como el parámetro de la función, a diferencia de las llamadas a las funciones normales, en las que en algunos casos se puede omitir el receptor porque se sobrentiende:
class Abecedario { infix fun sumar(s: String) { ... } fun masLetras() { this sumar "abc" // usando la anotación infix sumar("abc") // llamada común a la función (omisión de this) sumar "abc" // ERROR: se debe especificar el receptor } }
Otro ejemplo de función infix:
class Piramide { // función infix miembro de clase con un solo parámetro infix fun construirAltura(piso: Int) { var k: Int for (i in 1..piso) { k = 0 for (espacio in 1..piso - i) { print(" ") } while (k != 2 * i - 1) { print("* ") ++k } println() } } } fun main() { val piramide = Piramide() piramide construirAltura 5 // piramide.construirAltura(4) }
* * * * * * * * * * * * * * * * * * * * * * * * *
Comentarios
Publicar un comentario