Is it possible to return the same type as the type parameter when the operator

For example:

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.
    }

      

It gives compilation errors:

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

      

+3


source to share


2 answers


Then you can pipe the result T

. You won't get any help from the compiler and you will get warnings, but at least it will compile:

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

      



Note that when (a)

it is not necessary here, just when {

enough.

+6


source


Currently, when the Kotlin compiler parses a function, it does not accept certain special cases of type parameter for body parts.

Instead, code that works with a type parameter T

must be correct with any T

. Returning Int

where expected T

is not considered safe just because it is not sufficiently parsed to prove that T

it is always a supertype Int

if a function reaches that branch.

One option is to make an uncontrolled spike on T

, as in @ nhaarman's answer, thereby expressing that you are sure the types are correct.

Another solution is to make several overloads of your function that work with different types:

fun f(a: Int) = 1
fun f(a: String) = ""
fun f(a: Any): Nothing = throw RuntimeException()

      



In this case, the compiler will choose to overload the function based on the argument you pass, as opposed to specializing one generic function for a specific type argument, and this is an easier task for the compiler since it does not include any type of analysis inside the function body.


Also, a similar question:

+4


source







All Articles