为什么这个不可为 null 的 val 变成 "nullable"?

Why does this non-nullable val become "nullable"?

所以我有一个简单的回调class:

class Callback<T>(
    val onResponse: (T) -> Unit,
    val onError:(Throwable)->Unit
)

现在我想实现一个处理错误的方法。可能有也可能没有需要调用的 callback

private fun handleServerError(error:IServerError, callback:Callback<*>? = null){
    val reason = error.cause

    when(reason){
        is Because.ServerRejectsLogin -> {
            doAsync { uiThread { mainActivity.longToast("sorry, your session timed out. please log in again.") } }
            IntentManager.doLogin(mainActivity)
        }
        else -> callback?.onError(reason)
    }
}

这让我出错:

Reference has a nullable type ((Throwable) -> Unit)? use explicit ?.invoke() to make a function-like call, instead

似乎期待的是

else -> callback?.onError?.invoke(reason)

我不太明白为什么。 callback 不为空的事实是否足以推导出必须有一个非空的 onError 函数?

雪上加霜,如果我写

else -> callback?.let{it.onError(reason)}

然后它会接受,但不会在警告我应该

之前

remove redundant .let call

如果您使用安全调用运算符在 callback 对象上调用名为 onError 的函数,则 callback?.onError() 语法是正确的。但是,在这种情况下,您首先读取 callback 的 属性,然后根据 属性 返回的内容调用另一个函数。

所以不是由一步和两部分组成的表达式:

callback   ?.onError()

你实际得到的是一个由三部分组成的表达式,一行中有两个运算符:

callback   ?.onError   ()

此处的最后一步 () 是调用 onError returns:

对象的 invoke 运算符
callback   ?.onError   .invoke()

但是,由于 onError 属性 是使用安全调用运算符读取的,因此该对象可能是 null。在这种情况下,您不能在其运算符形式中使用 invoke(顺便说一句,任何其他运算符也是如此),因此您必须明确地将其写出来,并添加另一个安全调用:

callback   ?.onError   ?.invoke()

至于告诉您可以删除冗余的意图操作let:这是一个错误,应该在the issue tracker上报告。