Skip to main content
**More Information**
  • This is the 21st post in a multipart series.
    If you want to read more, see our series index

Today we tackle a weird operator, invoke which lets an instance of a class have a default function - which I am not sure I’ve ever seen any language do. So let us frame this with a simple example, we have a config class which returns the configuarion for something:

class Config { fun get():String { // do stuff return "stuff" } }

fun main(args: Array) { val config = Config() println(config.get()) }

Now, in our world maybe get is the primary use, so we can actually make it that the instance config (line 9) can be called to get it:

class Config { operator fun invoke(): String { return this.get(); }
private fun get():String {
    // do stuff
    return "stuff"
}

}

fun main(args: Array) { val config = Config() println(config()) }

Note that we add a new operator (line 2), and that calls the private get; it didn’t need to be private but I thought let us have this be cleaner, and now on line 14 we can just call the instance itself.

Now, you may be thinking… nice but so what saving a few keystrokes isn’t too awesome. Well, invoke can return anything, including itself which opens up something crazy.

class Config { var count = 0; operator fun invoke(): Config { count++ return this } }

fun main(args: Array) { val config = Config() config()()()()()()()()()() println(“config was called ${config.count} times”) }

This will print out config was called 10 times. That is getting more interesting, so let us ramp up another level and pass parameters to invoke:

class Config { var word = "" operator fun invoke(s: String): Config { word += s return this } }

fun main(args: Array) { val config = Config() config(“R”)(“o”)(“b”)(“e”)(“r”)(“t”) println(config.word) }

While I do not know yet where I would use this myself, I do use invoke all the time… since it is what makes lambdas possible in Kotlin as when we create a lambda we get an object which is invoked with well… invoke.