kotlinlambdafunctional-programmingreceiverextension-function

Unexpected behavior of also/apply, cannot pass references of a instance function into also/apply


To sum up the question in a few words, here is the catch:

The also(strings::add) doesn't work, it says Type inference failed

fun test() = "Test String"

val strings = mutableListOf<String>()
// Type inference failed: inline fun <T> T.also(block: (T) -> Unit): T cannot be applied to receiver: String arguments: (<unknown>)
// None of the following functions can be called with the arguments supplied: public abstract fun add(index: Int, element: String): Unit defined in kotlin.collections.MutableList public abstract fun add(element: String): Boolean defined in kotlin.collections.MutableList
test().also(strings::add).let { /* Use the string later */ }

While doing the same with let does work in the same place:

val strings = mutableListOf<String>()
test().let(strings::add).let { println(it) }  // prints true, no compile errors.

Here is the minimal reproducable code.

I want to use the string later so don't want to use let here. What should I do? If i try to use the apply the same compile error occur probably because both also and apply have same callback signature of KFunction1<T, T>. How should one pass these type of references with also/apply?


Solution

  • override fun add(element: E): Boolean as you can see, the function returns Boolean, but apply accepts block: T.() -> Unit, i.e. it accepts only functions that receive a single argument and return no value.