10

The following does not compile:

fun<T> doSomething(value: T, action: (value: T) -> String = Any::toString){
  //do something
}

The error is:

Kotlin: Type mismatch: inferred type is KFunction1<Any, String> but (T) -> String was expected

Making it work is easy:

fun<T> doSomething(value: T, action: (t: T) -> String = {t -> t.toString()}) = action(value)

However, this leaves me wondering: what is the difference between lambdas and KFunctions? Why do we need both?

Also is there a simpler way to provide Any::toString as the default action?

1
  • Any: causing problem Commented Sep 10, 2018 at 13:26

3 Answers 3

4

The reason why the code does not compile has nothing to do with the difference between lambdas and KFunctions. It doesn't compile because the parameter needs to be a function of type (T) -> String, and Any::toString is a function of type (Any) -> String.

Sign up to request clarification or add additional context in comments.

2 Comments

Sure, but replacing Any::toString with T::toString won't compile either. I can pass a lambda, but is there a simper way?
I don't think there is.
2

It would have compiled if do like this:

fun <T> doSomething(value: T, action: (value: Any) -> String = Any::toString) {
    //do something
}

or

fun <T : Any> doSomething(value: T, action: (t: T) -> String = Any::toString) {
    // ...
}

Comments

1

When you obtain any function (lambda or otherwise) reference with :: you are using reflection. KFunction is Kotlin's way to to wrap around reflected functions.

As to making Any::toString work - there is a way but you may not like it:

fun <T> doSomething(value: T, action: (t: T) -> String = Any::toString as (T) -> String) { 
    // ...
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.