尝试返回已检查通用参数的值时,为什么会出现类型不匹配?

mfu*_*n26 7 kotlin

在以下代码"Happy Halloween!"42,等等被标记为"类型不匹配".(必需:T,Found:String(或Int))但编译器是否应该能够从类型检查中推断返回值的类型是否正确?

interface Type<T>
class StringType() : Type<String>
class IntType1() : Type<Int>
class IntType2(val a: Int, val b: Int) : Type<Int>

fun <T> something(type: Type<T>): T = when (type) {
    is StringType -> "Happy Halloween!"
    is IntType1 -> 42
    is IntType2 -> type.a * type.a + type.b * type.b + type.a * type.b
    else -> throw IllegalArgumentException()
}
Run Code Online (Sandbox Code Playgroud)

Lea*_*ira 0

当编译器应用类型擦除时,将定义返回类型。因此,假设您使用 String...您的方法将类似于:

fun something(type: Type<String>): String = when (type) {
    is StringType -> "Happy Halloween!"
    is IntType1 -> 42 //Wrong: you must return String!
    is IntType2 -> type.a * type.a + type.b * type.b + type.a * type.b   
    else -> throw IllegalArgumentException()
}
Run Code Online (Sandbox Code Playgroud)

这件事是:你必须在编译时知道你的返回类型。如果你不知道这一点,你必须告诉编译器:

fun <T> something(type: Type<T>): Any = when (type) {
    is StringType -> "blabla"
    is IntType1 -> 42
    is IntType2 -> type.a * type.a + type.b * type.b + type.a * type.b
    else -> throw IllegalArgumentException()
}
Run Code Online (Sandbox Code Playgroud)

抱歉,这段代码不是您想要的,您将在方法返回后进行强制转换...

但你可以这样:

fun <T> something(type: Type<T>): T = when (type) {
        is StringType -> type.b
        //is IntType1 -> 42 remove this!
        is IntType2 -> type.a * type.a + type.b * type.b + type.a * type.b
        else -> throw IllegalArgumentException()
    }
Run Code Online (Sandbox Code Playgroud)

假设 type.a 和 type.b 被参数化为 T。那么您的代码将正常工作。