过载分辨率模糊。所有这些功能都匹配

时间:2018-02-15 10:15:56

标签: kotlin

我试图检查,在使用引用运算符的函数中初始化或不初始化变量。在这种情况下,函数名称和变量名称相同。所以Kotlin抛出

  

重载分辨率模糊。所有这些功能都匹配

异常。实际上这段代码有什么问题?

    DECLARE @StartDate datetime
    DECLARE @EndDate datetime
    SET @StartDate = '2018-01-01'
    SET @EndDate = '2018-01-31'

   SELECT EmpId,  COUNT(*) as DaysWorked 
    FROM
    (
      SELECT DISTINCT EmpId,CAST(TimeIn AS DATE) AS [Date]
      FROM myTable
      WHERE TimeIn IS NOT NULL
      AND CAST(TimeIn AS DATE) BETWEEN @StartDate AND @EndDate
    )T
    GROUP BY EmpId
    ORDER BY EmpId

4 个答案:

答案 0 :(得分:3)

这是一个简单的名字冲突。编译器不知道您是否引用方法abc或属性abc。重命名修复了问题:

class MyClass {
    private lateinit var abc: ABC

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

答案 1 :(得分:1)

问题是您有一个名为abc的属性,可以通过调用Kotlin属性访问器this.abc(某种“getter”)来访问它,并定义另一个具有相同名称的方法,所以它无法识别哪一个用语法::abc引用。

来自IDE的错误消息也说明了这一点:

  

重载分辨率模糊。所有这些功能都匹配:

     
      
  • private final lateinit var abc:在MyClass中定义的ABC
  •   
  • public final fun abc():MyClass中定义的单位
  •   

答案 2 :(得分:1)

如果您在没有引用语法的情况下访问MyClass实例上的函数abc或属性abc,它实际上会起作用,尽管我不推荐它。见这里:

class ABC

class MyClass{
    private lateinit var abc: ABC

    fun abc(){
        abc
    }
}

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

此代码编译没有任何问题。

但这不是你想要的。创建一个支持字段_abc并通过没有支持字段abc的属性访问它。这样,如果ABC尚未初始化,您可以返回_abc的默认实例。

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
}

输出:

  

未初始化
  初始化

答案 3 :(得分:0)

您可以通过提取变量并明确指定其类型来消除引用的歧义:

class ABC

class MyClass {
    private lateinit var abc: ABC

    fun abc() {

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