How to resolve overload ambiguity in method references?

3k Views Asked by At

Say I want to assign the java method Log.d(String, String) to a variable x of method type (String, String) -> Int and I do it like this:

val x: (String, String) -> Int = android.util.Log::d

The compiler says:

Error:(50, 56) Overload resolution ambiguity:
public open fun d(tag: kotlin.String!, msg: kotlin.String!): kotlin.Int defined in android.util.Log
public open fun d(tag: kotlin.String!, msg: kotlin.String!, tr: kotlin.Throwable!): kotlin.Int defined in android.util.Log

Obviously there is a second method Log.d(String, String, Throwable) but how do I tell the compiler which one I want?

2

There are 2 best solutions below

7
On BEST ANSWER

Disambiguation here is currently unsupported (will be supported later).

As a workaround, you can use a lambda expression:

{ s, s1 -> android.util.Log.d(s, s1) }
0
On

To resolve it you have to specify the type of the variable explicitly:

fun foo(i: Int) = 1
fun foo(str: String) = "AAA"

fun main() {
  val fooInt: (Int) -> Int = ::foo
  println(fooInt(123)) // 1
  val fooStr: (String) -> String = ::foo
  println(fooStr("")) // AAA
}

case with constructors:

class StudentId(val value: Int)
data class UserId(val value: Int) {
   constructor(studentId: StudentId) : this(studentId.value)
}

fun main() {
   val intToUserId: (Int) -> UserId = ::UserId
   println(intToUserId(1)) // UserId(value=1)

   val studentId = StudentId(2)
   val studentIdToUserId: (StudentId) -> UserId = ::UserId
   println(studentIdToUserId(studentId)) // UserId(value=2)
}