fun handle() : String { null?.let { return "Ololo"} } val result = handle() result.trim() // kotlin.TypeCastException: null cannot be cast to non-null type kotlin.CharSequence¿Alguna idea de por qué la función Kotlin de seguridad nula devuelve nulo?
Parece que el compilador de Kotlin está agregando un retorno null en caso de let no se ejecute. Probablemente se trate de un error, ya que no debería compilarse y no lo hace en versiones anteriores de Kotlin.
Si solo compilamos su ejemplo, obtenemos esto:
@NotNull public final String handle() { return null; } Creo que es solo una optimización del compilador, ya que null?.let() nunca se ejecutará.
Usando una variable real se obtiene:
@NotNull public final String handle() { return someNullableVariable != null ? "Ololo" : null; } En otras palabras, let() no se ejecuta si su referencia es null . Sin embargo, dado que esta función necesita devolver algo, el compilador simplemente le dice que devuelva null , ya que no hay nada más que pueda devolver.
Dado que la función está marcada como @NotNull , Kotlin realizará una verificación nula de todo lo que haga referencia a la función:
fun someOtherMethod() { handle().trim() }se convierte
public final void someOtherMethod() { String handle = handle(); if (handle != null) { StringsKt__StringsKt.trim(handle).toString(); return; } throw new Exception("null cannot be cast to non-null type kotlin.CharSequence"); } Hay dos formas de manejar esto. ¿Podría cambiar el tipo de devolución en handle() a String? :
fun handle(): String? { someNullableVariable?.let { return "Ololo" } }O podría devolver algo más en caso de que la variable sea nula:
fun handle(): String { someNullableVariable?.let { return "Ololo" } return "someNullableVariable was null" }Tiene que ser un error, porque:
let no se invocaráString como tipo de retorno nunca debe devolver null .Curiosamente, en Kotlin 1.2.x esto ni siquiera compila:
fun handle() : String { null?.let { return "Ololo"} }Error:(6, 0) Se requiere una expresión de 'retorno' en una función con un cuerpo de bloque ('{...}')
En Kotlin 1.3.11 lo hace.
En todo caso:
let no será invocado, porque el operador de llamada segura ? se evalúa como null (en este caso).