Search code examples
kotlinkotlin-extension

Extension and higher-order functions referencing


I get an overall idea of what is each of these, I wrote piece of code however that I don't quite understand why it works.
The thing is callExtensionOnString expects extension function as its parameter, however it doesn't complain if reference to printString is passed. Is String.() -> Unit just another name for (String) -> Unit type or is it Kotlin compiler that takes some kind of shortcut to fit higher order in extension function?

fun main(args: Array<String>) {
    callExtensionOnString(::printString)
}

fun callExtensionOnString(extensionFun: String.() -> Unit) {
    "testString".extensionFun()
}

fun printString(str: String) {
    println(str)
}

Then there is second thing that seems unclear to me. printString reference is passed once to callExtensionOnString and then again to run function which basically requires String.() -> Unit extension function. Is there difference between these two so that second time :: prefix is omitted?

fun main(args: Array<String>) {
    runFunctionOnString(::printString)
}

fun runFunctionOnString(higherOrderFun: (String) -> Unit) {
    "testString".run(higherOrderFun)
}

fun printString(str: String) {
    println(str)
}

Solution

  • Concerning your first question, these 2 are equivalent:

    "testString".extensionFun()
    extensionFun("testString")
    

    That's why passing printString method doesn't cause a compilation error.

    Concerning the second question, the difference is that highOrderFun is already a reference to a function, while printString is not a function reference (but you can obtain it with the :: operator)