是否可以在when语句中返回与type参数相同的类型
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以在when语句中返回与type参数相同的类型相关的知识,希望对你有一定的参考价值。
例如:
fun <T> f(a: T): T =
when (a) {
a is Int -> 0 // if T is Int, then return Int
a is String -> "" // if T is String, then return String
else -> throw RuntimeException() // Otherwise, throw an exception so that the return type does not matter.
}
它给出了编译错误:
Error:(3, 20) The integer literal does not conform to the expected type T
Error:(4, 23) Type mismatch: inferred type is String but T was expected
答案
之后您可以将结果投射到T
。您将无法获得任何编译器帮助,您将收到警告,但至少它会编译:
fun <T> f(a: T): T =
when {
a is Int -> 0 // if T is Int, then return Int
a is String -> "" // if T is String, then return String
else -> throw RuntimeException() // Otherwise, throw an exception so that the return type does not matter.
} as T
请注意,when (a)
在这里是不必要的,只需when {
即可。
另一答案
目前,当Kotlin编译器分析函数时,它不假设身体各部分的类型参数的某些特定情况。
相反,使用类型参数T
的代码应该对任何T
都是正确的。返回Int
预期T
不被认为是安全的,因为它的分析不够深,无法证明如果函数到达那个分支,T
总是Int
的超类型。
一个选项只是对T
进行未经检查的转换,就像在@nhaarman的回答中一样,表示你确定类型是正确的。
另一种解决方案是使用不同类型的函数进行多次重载:
fun f(a: Int) = 1
fun f(a: String) = ""
fun f(a: Any): Nothing = throw RuntimeException()
在这种情况下,编译器将根据您传递的参数选择函数重载,而不是将单个泛型函数专门化为某个类型参数,这对于编译器来说是一个更简单的任务,因为它不涉及任何类型分析在函数体内。
另外,类似的问题:
以上是关于是否可以在when语句中返回与type参数相同的类型的主要内容,如果未能解决你的问题,请参考以下文章