How to deal with the problem of overloading the ambiguity of functions with generics?

Consider this class with two functions: one with an argument Int , the other with a common:

 class C<K, V> { // ... operator fun f(index: Int): Pair<K, V> = ... operator fun f(key: K): V = ... } 

When it is parameterized as C<Int, SomeType> , K is equal to Int , and both functions correspond to calls, which leads to an error:

 val m = C<Int, SomeType>() mf(1) 

Uncertainty of overload resolution. All these functions correspond to:

  • public final fun f(index: Int): SomeType defined in C
  • public final fun f(key: Int): Pair<Int, SomeType>? defined in C

How do I call f in this case?

+5
source share
2 answers

If you are lucky enough to have different function parameter names, using named arguments will do the trick:

 mf(index = 1) // calls f(index: Int) mf(key = 1) // calls f(key: K) 

Otherwise, if the parameter names are the same (or defined in Java), one of the possible workarounds is to perform untested throws so that the compiler chooses the desired option:

  • To call f(index: Int) you can use

     @Suppress("UNCHECKED_CAST") val s = (m as C<*, SomeType>).f(1) as Pair<Int, SomeType> 

    The cast to C<*, SomeType> makes K equivalent in Nothing, out Any , which means that f(key: K) no valid argument, so the call is naturally resolved by f(index: Int) , but you need to return the result back , because otherwise it is Pair<Any, SomeType> .

  • To call f(key: K) use:

     @Suppress("UNCHECKED_CAST") val s = (m as C<Any, SomeType>).f(1 as Any) 

    Similarly, casting to C<Any, SomeType> changes the signature of the desired function to f(key: Any) , and to call it, just drag 1 to Any .

This is the same if several types are merged (for example, f(key: K) and f(value: V) , when K and V are SomeType ), just use named arguments or drop the object to disable one of the function ( in Nothing ) or make him accept Any .

+7
source

Kotlin stdlib uses the fun fAt(index: Int) convention to resolve such cases.

0
source

Source: https://habr.com/ru/post/1260083/


All Articles