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?


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".

Refer more here.


this is a good question. so when you have this kind of statement: T.()

it means that in the lamda you will be passing in, "this" (which is the current object) will be of type T. Lets take a look how easy it its to understand:

Lets say we have some class with a function called myFun which takes in a lambda defined like this:

 class MyObject {
        fun myFun(doSomething: MyObject.()->Unit) {
            doSomething()
        }

        fun doAnotherThing() {
            Timber.d("myapp", "doing another thing")
        }
    }

to call this function i'd do this:

MyObject().myFun { doAnotherThing() }

see how it knew to use the MyObject() reference as the "this". this is really calling this.doAnotherThing() where this is the Myobject() instance just created.

could have also done this:

MyObject().apply{myFun { doAnotherThing() }}  

Answer of @Kris Roofe make the things clear. Let me add more to it.

fun Activity.drawer means that we are making an extension function name drawer in Activity class. That's the reason we can call drawer method directly from an Activity class or child of an Activity class.

More on extension functions here.

(setup: DrawerBuilderKt.() -> Unit = {}) In this statement we can see the power of kotlin higher order functions. Small intro of Higher order functions :- It is a function that takes functions as parameters, or returns a function. So here setup param is a function which return Nothing or Unit(Same as Void in java). DrawerBuilderKt.() means that the function can be invoked using object of DrawerBuilderKt class. = {} means that setup parameter is optional. So the function takes no parameters and return nothing.

More on Higher order functions here and here. More on optional parameter here.

private val View.viewFinder: View.(Int) -> View? it store a function in a property. Here more info about the same. Rest of the things are same as explained above.

Hope this will help.


There is a misunderstanding that T.() -> Y is (T.()) -> Y, but actually is T.(()->Y). As we know (X)->Y is a lambda, so T.(X)->Y is an extension on T.

If there is no parameter, the form is T.() -> Y

It's interesting that we can call it in two ways as the blew.

import kotlinx.coroutines.*


open class MyClass(var name: String){
    open fun something(){println("myclass something")}
}


fun main() = runBlocking{
    val me = MyClass("Boll")
    val someMethod: MyClass.(Int) -> String = { n ->
        List(n){"X"}.joinToString(separator="", postfix=":${this.name}")
    }
    val some = me.someMethod(10)
    //val some = someMethod(me, 10)
    println(some)

    val anotherMehtod: MyClass.() -> String = { 
        "Y:"+this.name
    }
    //val another = me.anotherMehtod()
    val another = anotherMehtod(me) 
    println(another)
}