Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get a type mismatch when attempting to return a value for a checked generic parameter?

Tags:

kotlin

In the following code "Happy Halloween!", 42, etc. are flagged as "Type mismatch." (Required: T, Found: String (or Int)) but shouldn't the compiler be able to infer that the return value is of the correct type from the type check?

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()
}
like image 909
mfulton26 Avatar asked Oct 31 '16 21:10

mfulton26


1 Answers

You could write this:

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

inline fun <reified T> something(type: Type<T>): T {
    val result = 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()
    }
    return if (result is T) result else throw Exception() 
}

Running the following:

fun main(args: Array<String>) {
    println(something(StringType()))
    println(something(IntType1()))
    println(something(IntType2(2, 3)))
}

Will give you this output:

Happy Halloween
42
19

Learn more about inline functions and reified parameters here: Reified type parameters.

like image 123
janosch Avatar answered Jan 03 '23 01:01

janosch