Why would this code not work?
val f: (String) -> Unit = { it -> println(it.length) }
val x = "hello".also(::f)
This prints out these error messages:
error: type inference failed: inline fun <T> T.also(block: (T) -> Unit): T
cannot be applied to
receiver: String arguments: (KProperty0<(String) -> Unit>)
val x = "hello".also(::f)
^
error: type mismatch: inferred type is KProperty0<(String) -> Unit> but (String) -> Unit was expected
val x = "hello".also(::f)
^
While
val x = "hello".also(::println)
would work, why would above not? What is KProperty0<>
from the error message?
It needs to be
val x = "hello".also(f)
The reference syntax ::f would work only if f is a function. But it is a property that holds a function.
Alternatively, you can change f to be a function.
1 Like
Oh I see… Thanks for the explanation!
But now I wonder.
In case of lambda expressions, for example,
val square: (Int)->Int = { x -> x * x }
We use square
just as if it was a function
square(2)
If square is not a function, but a property that holds a function,
what’s happening under the hood so that we could use the notation square(2)
?
Under the hood it calls square.invoke(2). There just happens to be a shorthand syntax for it (see invoke operator overloading).
It is a bit inconsistent that there is not a shorthand syntax for function references, too.
1 Like
Thanks, that helped me clarify quite a lot