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)
}
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)