Home > Mobile >  Same type for receiver and argument in Kotlin function
Same type for receiver and argument in Kotlin function

Time:11-27

Is there any difference between these two Kotlin extension functions?

fun Any?.f(o: Any?) = 100

fun <T> T.g(o: T) = 100

Is it possible to rewrite g in such a way that the type of its argument and receiver are forced to be the same?

That is, 10.g(5) and "x".g("y") are OK, but 10.g("y") does not compile.

Edit: Given this, I guess the answer to my second question is no, uless one adds additional arguments.

CodePudding user response:

I believe this is not possible officially at the time of writing this answer (Kotlin 1.7.20).

However, internally Kotlin compiler supports such case, it allows to change the default behavior and use exact type parameters. This is controlled by the internal @Exact annotation and it is used in many places across the Kotlin stdlib.

With some hacking we can enable this behavior in our own code:

@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
fun <T> @kotlin.internal.Exact T.g(o: @kotlin.internal.Exact T) = 100

Of course, this is purely a hack and it may stop working in future versions of Kotlin.

Update

Answering your first question on whether there is a difference between using Any and T. Generic functions make the most sense if the type parameter is not only consumed, but also passed somewhere further. For example, if the function returns T or it receives an object that consumes T:

fun main() {
    var result = 5.g(7)
}

fun <T> T.g(o: T): T = if (...) this else o

In this case result is of type Int. If we use Any instead of T, result would have to be Any as well.

  • Related