是否可以在when语句中返回与type参数相同的类型

时间:2017-06-16 11:52:51

标签: generics types kotlin

例如:

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

2 个答案:

答案 0 :(得分:6)

之后您可以将结果转换为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 {即可。

答案 1 :(得分:4)

目前,当Kotlin编译器分析一个函数时,它不会假设身体各部分的某些特定类型参数的情况。

相反,使用类型参数T的代码应该与任何T一致。返回预期Int的{​​{1}}不被认为是安全的,因为它的分析不够深,无法证明T始终是T的超类型功能到达那个分支。

一个选项就是对Int进行未选中的转换,就像在@nhaarman的回答中一样,表示您确定类型是正确的。

另一种解决方案是使用不同类型的函数进行多次重载:

T

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

此外,类似的问题: