Overload resolution ambiguity. All these functions match

≯℡__Kan透↙ 提交于 2021-01-26 11:02:22

问题


I tried to check, lateinit variable is initialized or not in a function using reference operator. The function name and variable name is same in this case. So that Kotlin throws

Overload resolution ambiguity. All these functions match

exception. Actually what's wrong in this code?

class ABC

class MyClass {
    private lateinit var abc: ABC

    fun abc() {
        if(!::abc.isInitialized){
            println("Hello")
        }
    }
}

回答1:


It's a simple name clash. The compiler does not know whether you're referring to the method abc or the property abc. A renaming fixes the problem:

class MyClass {
    private lateinit var abc: ABC

    fun abcFun() {
        val prop = this::abc
        if (!::abc.isInitialized) {
            println("Hello")
        }
    }
}



回答2:


The issue is that you have a property called abc, which can be accessed by calling the Kotlin property accessor this.abc (sort of "getter") and you define another method with the same name, so it doesn't recognize which one to reference with syntax ::abc.

This is also stated by the error message from the IDE:

Overload resolution ambiguity. All these functions match:

  • private final lateinit var abc: ABC defined in MyClass
  • public final fun abc(): Unit defined in MyClass



回答3:


If you would access the function abc or the property abc on an instance of MyClass without the reference syntax, it would actually work, although I would not recommend it. See here:

class ABC

class MyClass{
    private lateinit var abc: ABC

    fun abc(){
        abc
    }
}

fun main(args: Array<String>) {
  val c = MyClass()
  c.abc()
}

This code compiles without any problems.

But this is not what you want. Create a backing field _abc and access it via a property without backing field abc. This way you can return a default instance of ABC, if _abc has not been initialized.

class MyClass {

    private lateinit var _abc: ABC

    val abc: ABC get() {
        if(!::_abc.isInitialized){
            println("Uninitialized")
            return ABC() // some default instance
        }
        println("Initialized")
        return _abc
    }

    fun initABC() {
        _abc = ABC()
    }
} 

fun main(args: Array<String>) {
  val c = MyClass()
  c.abc
  c.initABC()
  c.abc
}

Output:

Uninitialized
Initialized




回答4:


You can disambiguate the reference by extracting a variable and explicitly specifying its type:

class ABC

class MyClass {
    private lateinit var abc: ABC

    fun abc() {

        val abc: KProperty0<ABC> = ::abc
        if(!abc.isInitialized){
            println("Hello")
        }
    }
}


来源:https://stackoverflow.com/questions/48804704/overload-resolution-ambiguity-all-these-functions-match

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!