首页 > 解决方案 > 'Any' 类型的表达式 'classLevel' 不能作为函数调用。未找到函数“invoke()”

问题描述

考虑以下类:

class Test {
    val classLevel = object {
        operator fun invoke() = println("test class level property invocaton")
    }

    fun foo() {
        val functionLevel = object {
            operator fun invoke() = println("test invocation")
        }
        functionLevel() // no problem
        classLevel() // Expression 'classLevel' of type 'Any' cannot be invoked as a function. The function 'invoke()' is not found
    }
}

为什么第二个调用,即类属性的调用,不编译?它的声明方式与函数中相同。

标签: kotlin

解决方案


我认为这是关于类型的。

classLevel字段是匿名类型(Any由对象表达式创建的 的子类型)。该类型有一个invoke()方法。

但是,该类型在课堂之外是不可见的。所以如果属性有getter(即它不是私有的),getter 不能返回匿名类型;它必须返回最接近的命名类型,即Any. 而且Any没有invoke()方法。

我不确定类中的代码是否会使用 getter 方法(如果可用),或者基础字段的类型是否必须与 getter 的类型(如果存在)完全匹配。但无论哪种方式,结果很明显,如果有一个 getter,classLevel在类中引用会得到一个Any引用,所以你不能调用invoke()它。(并且您不能向下转换对您的对象类型的引用invoke(),因为该类型没有名称。)

如您所见,一种解决方案是将字段设为私有;这将删除 getter,并允许其底层类型成为实际的对象类型,这就是为什么invoke()可以调用的原因。

另一个可能是为要实现的对象定义一个命名类型。


推荐阅读