JP
02/23/2020, 3:01 AMval 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<>
?Kiryushin Andrey
02/23/2020, 6:58 AM::f
is a reflection handle for the property f
of the functional type, that's why KProperty
comes into picture. What you get here with the ::
operator is actually a callable reference that can be passed to higher-order function, but this is a function that takes nothing as input and returns a function as return value - so its signature doesn't match the signature expected by the also
function, that's what the compiler is complaining about.
In your sample you don't need this reference in order to pass a value of functional type to higher-order function, so instead just call it like:
"hello".also(f)
Another option is to declare f
as a function, not as a property. You can't pass a declared function directly as a parameter for the higher-order function, you need to obtain a callable reference to the function to do this. So in this case ::
operator is needed:
fun f(it: String) = println(it.length)
"hello".also(::f)
See more here https://kotlinlang.org/docs/reference/reflection.htmlDominikus
02/23/2020, 12:38 PMString
is a compile time reference to this very class. String::class
gets you a runtime reference to a Kotlin class, which is a value of type KClass
. (See https://kotlinlang.org/docs/reference/reflection.html#class-references)