如何不从 Kotlin 块返回最后一个表达式的值?



我有一个不返回任何值的方法。在它里面,有一个try-catch块:

override fun sendResourceCreationRequest(...) {
try {
val requestEntity = ...
restTemplate.exchange(requestEntity)
} catch (e: RestClientException) {
...
}
}

因为try块中最后一个表达式的值是隐式返回的,所以我得到了这个编译器错误:

Type mismatch.
Required: Nothing
Found: ResponseEntity<???>

我可以把值赋给一个变量,错误就会消失:

val response: ResponseEntity<Unit> = restTemplate.exchange(requestEntity)

但是现在我有一个我(和lint)不喜欢的未使用的变量。处理这件事的最好方法是什么?


编辑

当我显式指定响应类型时,错误消失了:

restTemplate.exchange<Unit>(requestEntity)

也许与交换是内联具体化函数或其他什么有关?

@Throws(RestClientException::class)
inline fun <reified T> RestOperations.exchange(requestEntity: RequestEntity<*>): ResponseEntity<T> =
exchange(requestEntity, object : ParameterizedTypeReference<T>() {})

首先,我不是百分之百确定这里发生了什么,但我认为你误解了这个情况。此错误与sendResourceCreationRequest()的返回类型无关。假设样本(几乎)完整,该函数不返回Nothing,而是返回Unit,因此错误消息没有太大意义。此外,last表达式仅在lambdas中隐式返回,而在常规函数中不会返回。本例中restTemplate.exchange(requestEntity)表达式的值没有真正返回,而只是忽略。

问题是不同的。exchange()是参数化的,需要提供自己的T,才能正常工作。这两个代码片段都提供了T:

restTemplate.exchange<Unit>(requestEntity)
val response: ResponseEntity<Unit> = restTemplate.exchange(requestEntity)

然而,在你的原始代码(restTemplate.exchange(requestEntity))中,T是未知的。

仍然,我不知道为什么你得到关于Nothing的错误,而不是T不能推断。这可能与exchange()内部函数的内容有关。

但无论如何,你的问题的直接答案是你应该使用exchange<Unit>()。我只是不确定这是否会为您工作,因为REST框架可能会尝试将响应解释为Unit,这可能不会工作。我不知道你使用的REST库是什么,你的情况到底是什么,但如果你只需要忽略响应,如果Unit不起作用,你可以尝试exchange<String>()。在许多REST框架中,这意味着:"不处理响应体,按原样返回"。

编译器将错误声明为Nothing,必须返回给方法sendResourceCreationRequest(),这意味着方法的签名必须是这样的:

abstract fun sendResourceCreationRequest(): Nothing

检查Nothing的定义:

/**
* Nothing has no instances.
* You can use Nothing to represent "a value that never exists":
* for example,
* if a function has the return type of Nothing,
* it means that it never returns (always throws an exception).
*/
public class Nothing private constructor()

由于sendResourceCreationRequest()的返回类型为Nothing,因此该方法必须抛出异常来停止进一步的执行。

从用例的角度来看,如果这不是方法的预期行为,只需删除返回类型Nothing并用Unit替换它。

abstract fun sendResourceCreationRequest(): Unit // Explicit way of saying method won't return anything.
// OR
abstract fun sendResourceCreationRequest() // Implicit way of saying method won't return anything.

相关内容

最新更新