Lo siguiente no compila:

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

El error es:

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

Hacer que funcione es fácil:

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

Sin embargo, esto me deja preguntándome: ¿cuál es la diferencia entre lambdas y KFunctions? ¿Por qué necesitamos ambos?

¿También hay una manera más simple de proporcionar Any :: toString como la acción predeterminada?

4
Dol.Gopil 10 sep. 2018 a las 16:17

3 respuestas

La mejor respuesta

Cuando obtiene cualquier referencia de función (lambda o de otro tipo) con ::, está utilizando la reflexión. KFunction es la forma en que Kotlin se ajusta a las funciones reflejadas.

En cuanto a hacer que Any::toString funcione, hay una manera, pero puede que no te guste:

fun <T> doSomething(value: T, action: (t: T) -> String = Any::toString as (T) -> String) { 
    // ...
}
1
David Soroko 10 sep. 2018 a las 14:35

La razón por la cual el código no se compila no tiene nada que ver con la diferencia entre lambdas y KFunctions. No se compila porque el parámetro debe ser una función del tipo (T) -> String, y Any::toString es una función del tipo (Any) -> String.

2
Tim 10 sep. 2018 a las 13:32

Se habría compilado si hiciera así:

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

O

fun <T : Any> doSomething(value: T, action: (t: T) -> String = Any::toString) {
    // ...
}
0
Shivam Bhusri 2 feb. 2020 a las 05:52