Search code examples
androidobjectkotlinnavigation-drawerhigher-order-functions

What does ".()" mean in Kotlin?


I've seen examples where a function has an argument given by ClassName.() This doesn't seem to be an extension function, which is ClassName.Function()

An example is Kotterknife:

private val View.viewFinder: View.(Int) -> View?
    get() = { findViewById(it) }

Which I don't quite know the function of,

and MaterialDrawerKt

fun Activity.drawer(setup: DrawerBuilderKt.() -> Unit = {}): Drawer {
    val builder = DrawerBuilderKt(this)
    builder.setup()
    return builder.build()
}

Where the code allows you to directly call

drawer {
    ...
}

rather than give it arguments surrounded by the parentheses.

Is there any documentation on this anywhere?


Solution

  • A function that takes in nothing and returns nothing in Kotlin looks like:

    var function : () -> Unit
    

    The difference is that the function in your code takes in nothing, returns nothing, but is invoked on an object.

    For example,

    class Builder (val multiplier: Int) {
        
        fun invokeStuff(action: (Builder.() -> Unit)) {
            this.action()
        }
        
        fun multiply(value: Int) : Int {
            return value * multiplier
        }
    }
    

    The important bit here is the way we've declared the type of action

    action: (Builder.() -> Unit)
    

    This is a function that returns nothing, takes in nothing but is invoked on an object of type Builder.

    This means when we use this builder like so

    var builder = Builder(10)
    builder.invokeStuff({
        var result = multiply(1)
        println(result)
    })
    

    The context of this has been set to the builder object and we can invoke functions declared within the builder.

    Refer more here.