fun handle() : String {
null?.let { return "Ololo"}
}
val result = handle()
result.trim() // kotlin.TypeCastException: null cannot be cast to non-null type kotlin.CharSequence
有什么想法为什么空安全的Kotlin函数返回空?
答案 0 :(得分:8)
答案 1 :(得分:4)
Kotlin编译器似乎在null
不执行的情况下添加了let
返回。这可能是一个错误,因为它不应该编译,也不在Kotlin的早期版本中。
如果我们只是编译您的示例,则会得到以下信息:
@NotNull
public final String handle() {
return null;
}
我认为这只是编译器优化,因为null?.let()
将永远不会执行。
使用实际变量会产生:
@NotNull
public final String handle() {
return someNullableVariable != null ? "Ololo" : null;
}
换句话说,如果let()
的引用是null
,则不会执行。但是,由于此函数需要返回某些内容,因此编译器只是告诉它返回null
,因为它没有其他返回值。
由于该函数被标记为@NotNull
,因此Kotlin将对引用该函数的所有内容执行空检查:
fun someOtherMethod() {
handle().trim()
}
成为
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");
}
有两种方法可以解决此问题。您可以将handle()
的返回类型更改为String?
:
fun handle(): String? {
someNullableVariable?.let { return "Ololo" }
}
或者,如果变量为null,则可以返回其他内容:
fun handle(): String {
someNullableVariable?.let { return "Ololo" }
return "someNullableVariable was null"
}
答案 2 :(得分:3)
这一定是个错误,因为:
let
的lambda不会被调用String
作为返回类型的函数永远不要返回null
。有趣的是,在Kotlin 1.2.x中,它甚至无法编译:
fun handle() : String {
null?.let { return "Ololo"}
}
错误:(6,0)具有块体('{...}')的函数中需要的'return'表达式
在Kotlin 1.3.11中可以。
无论如何:
let
将不会被调用,因为安全呼叫运算符?
的计算结果为null
(在这种情况下)。