Funciones infix

Funciones infix en Kotlin

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

Entradas populares

I/O: entrada y salida de datos en consola

Recursos gratis para aprender Kotlin

Lectura y escritura de archivos