mscharhag, Programming and Stuff;

A blog about programming and software development topics, mostly focused on Java technologies including Java EE, Spring and Grails.

Wednesday, 17 June, 2020

Kotlin infix functions

What are infix functions?

If you are using Kotlin chances are high you already used infix functions. Maybe without knowing it.

When calling infix functions it is possible to omit the dot and the parentheses. So instead of

car.move(forward)

we can write:

car move forward

Here are a few examples of commonly used infix functions in Kotlin. The standard call notation (including dot and parentheses) for these functions is shown as comment.

val map = mapOf(
    "foo" to 42     // "foo".to(42)
)

for (i in 0 until 5) {  // 0.until(5)
    ...
}

val regex = Regex("\\w")
if ("foo" matches regex) {  // "foo".matches(regex)

}

Writing your own infix function

Of course we can write our own infix functions.

Infix functions must satisfy the following requirements:

  • They must be member functions or extension functions
  • They must have a single parameter
  • The parameter must not accept variable number of arguments and must have no default value

To create an infix function we have to add the infix keyword to the function signature.

For example:

enum class TurnDirection { left, right }

class Car {
    infix fun turn(turnDirection: TurnDirection) { ... } // our infix function
}

fun main() {
    val car = Car()
    car turn left // infix function call, static import of "left" required   
}

If we return an object that contains an infix function itself, we can chain infix function calls.

For example:

class TurnDirectionBuilder {
    infix fun then(turnDirection: TurnDirection) { ... }
}

class Car {
    infix fun turn(turnDirection: TurnDirection): TurnDirectionBuilder {
        return TurnDirectionBuilder()
    }
}

fun main() {
    val car = Car()
    car turn left then right // same as: car.turn(left).then(right)
}

A common example of this in Kotlin is the IntProgression.step() function that might be used in for loops.

For example:

for (i in 0 until 10 step 2) { .. }  // same as: 0.until(10).step(2) 

 

Leave a reply