是否有可能在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() 

在这种情况下,编译器将根据您传递的参数来选择函数重载,而不是将某个泛型函数专用于某个类型参数,这对于编译器来说是一个更简单的任务,因为它不涉及任何类型分析在一个函数体内。


另外,类似的问题:

  • Kotlin实体类型参数不智能投射

  • 为什么不聪明处理这种情况呢?