请考虑以下课程:
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
}
}
为什么第二个调用(对类属性的第一个)不能编译?与函数中的声明方式相同。
答案 0 :(得分:1)
我认为这与类型有关。
classLevel
字段是匿名类型(Any
的子类型,由对象表达式创建)。该类型具有invoke()
方法。
但是,该类型在类外不可见。因此,如果该属性具有一个吸气剂(即它不是私有的),则该吸气剂不能返回匿名类型。它必须返回最接近的命名类型,即Any
。而且Any
没有invoke()
方法。
我不确定类中的代码是否将使用getter方法(如果可用),或者不确定基础字段的类型是否必须与getter的类型完全匹配(如果存在)。但是,无论哪种方式,结果显然是,如果有吸气剂,则在类中引用classLevel
会为您提供Any
引用,因此您不能在其上调用invoke()
。 (而且,您不能向下引用对您的对象类型的引用,该对象类型确实具有invoke()
,因为该类型没有名称。)
您发现,一种解决方案是将字段设为私有;删除吸气剂,并允许其底层类型为实际的对象类型,这就是为什么可以invoke()
进行调用的原因。
另一种可能是为要实现的对象定义一个命名类型。