kotlin - '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
}
}
为什么第二个调用,即类属性的调用,不编译?它的声明方式与函数中相同。
解决方案
我认为这是关于类型的。
该classLevel
字段是匿名类型(Any
由对象表达式创建的 的子类型)。该类型有一个invoke()
方法。
但是,该类型在课堂之外是不可见的。所以如果属性有getter(即它不是私有的),getter 不能返回匿名类型;它必须返回最接近的命名类型,即Any
. 而且Any
没有invoke()
方法。
我不确定类中的代码是否会使用 getter 方法(如果可用),或者基础字段的类型是否必须与 getter 的类型(如果存在)完全匹配。但无论哪种方式,结果很明显,如果有一个 getter,classLevel
在类中引用会得到一个Any
引用,所以你不能调用invoke()
它。(并且您不能向下转换对您的对象类型的引用invoke()
,因为该类型没有名称。)
如您所见,一种解决方案是将字段设为私有;这将删除 getter,并允许其底层类型成为实际的对象类型,这就是为什么invoke()
可以调用的原因。
另一个可能是为要实现的对象定义一个命名类型。
推荐阅读
- typo3 - 如果没有结果,则 TypoScript 内容使用另一个查询
- c# - 使用从 Azure AD 组中检索电子邮件 ID
- c++ - 虚幻 4.24.3:如何在 .cpp 文件中声明 UPROPERTY()
- html - CSS Grid 布局 IE11 不考虑尺寸
- javascript - 使用来自 MSSQL 和 node.js 网络服务器的实时数据可视化图表
- scala - 为什么 spark (scala API) agg 函数需要 expr 和 exprs 参数?
- vuex - Nuxt 在插槽中使用组件,vuex 存储未定义
- junit5 - 断言数组中的值,数组没有名称
- assembly - 在程序集中读取命令行参数
- listview - Flutter Listview 语言选择需要在选择时进行圆形复选框设计