什么是::SomeClass引用在Kotlin中

6vl6ewon  于 2022-12-13  发布在  Kotlin
关注(0)|答案(2)|浏览(139)

以下列程式码范例为例:

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自己的内置调用函数,而不是类中的运算符函数。

ao218c7q

ao218c7q1#

调用函数可以通过在类的一个示例后面编写()来调用。

x.invoke(10) {
    println("test")
}()

可以为你的例子工作,并打印“test”。或者这个例子

val s = x.invoke(10) {
    println("test")
}

s()
s()

打印测试两次

j9per5c4

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) {}返回的内容。

x(10) {
    println("foo")
}.invoke()

// or

x(10) {
    println("foo")
}()

以上任何一个都将打印“foo”。

相关问题