在以下代码"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)
当编译器应用类型擦除时,将定义返回类型。因此,假设您使用 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。那么您的代码将正常工作。