以下列程式码范例为例:
class Food(var size: Int, val doSomething: () -> Unit) {
init {
var t = 0
}
operator fun invoke() {
doSomething()
}
}
var x = ::Food
x.invoke(10) {
var x = 1
}
当x.invoke(10)
被调用时,Food中的init被调用,但是invoke函数没有被调用,这看起来很奇怪。如果实际的invoke函数没有被调用,那么::Food
引用的是什么,x.invoke
调用的究竟是什么?
看起来x引用了构造函数。您可以通过调用以下命令来调用构造函数:x(10) {}
但是包含.invoke
没有任何作用。构造函数仍然被调用(因此init),但是invoke函数本身没有任何作用。甚至不知道为什么允许这样做。
我有一种感觉,.invoke
正在调用Kotlin自己的内置调用函数,而不是类中的运算符函数。
2条答案
按热度按时间ao218c7q1#
调用函数可以通过在类的一个示例后面编写
()
来调用。可以为你的例子工作,并打印“test”。或者这个例子
打印测试两次
j9per5c42#
x
似乎指涉建构函式。你的观察是正确的,
x(10) {}
和x.invoke(10) {}
确实是一样的,前者只是后者的句法糖,就像1 + 1
只是1.plus(1)
的句法糖一样。实际上,这就是
invoke
操作符的全部意义,也是为什么可以直接调用函数/构造函数引用的原因。如果x
已经声明了invoke(...)
操作符,那么x(...)
就意味着x.invoke(...)
。::Food
是对Food
的构造函数的引用,它的类型为KFunction2<Int, () -> Unit, Food>
。此类型被指定为具有invoke()
运算符,该运算符接受Int
和() -> Unit
,并返回Food
。当执行x(10) {}
或x.invoke(10) {}
时,您调用的是 thatinvoke
运算符,而不是Food
中的那个。要在
Food
中调用invoke
,需要一个Food
的示例,该示例正是x(10) {}
或x.invoke(10) {}
返回的内容。以上任何一个都将打印“foo”。