Why would this code not work? ```val f: (String) -...
# getting-started
j
Why would this code not work?
Copy code
val f: (String) -> Unit = { it -> println(it.length) }
val x = "hello".also(::f)
This prints out these error messages:
Copy code
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
Copy code
val x = "hello".also(::println)
would work, why would above not? What is
KProperty0<>
?
k
The type of
::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:
Copy code
"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:
Copy code
fun f(it: String) = println(it.length)
"hello".also(::f)
See more here https://kotlinlang.org/docs/reference/reflection.html
👍 1
d
Basically,
String
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)