问题
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