function - 为什么不能在 Kotlin 中将“`main`”函数声明为 lambda?
问题描述
以下简单的 Kotlin 代码片段
fun main() {}
编译得很好,但以下
val main : () -> Unit = {}
使编译器抱怨“在项目中找不到主要方法。”,而我希望它们是等效的(我希望编程语言在概念上尽可能统一)。
为什么会这样?它仅与 相关
main
,还是这种行为涉及更大的函数类?用 " " 声明函数和将它们声明为 lambdas之间有什么细微的区别fun
吗?
解决方案
从概念上讲,它们是不同的东西。为了看到这一点,让我们大致看一下等效的 Java 是什么。我将在此答案中使用 JVM 作为示例,但相同的原则适用于所有其他 Kotlin 后端。
object Foo {
fun main() { ... }
}
这是大致
class Foo {
public static void main() { ... }
}
再次,大致。从技术上讲,除非你使用,否则你会得到一个单例对象和一个方法@JvmStatic
(我假设有一些特殊的处理main
会在 JVM 上产生一个静态函数,但我不知道这是事实)
另一方面,
object Foo {
val main: () -> Unit = { ... }
}
在这里,我们声明了一个属性,它在 Java 中将被实现为 getter-setter 对
class Foo {
// Singleton instance
public static Foo instance = new Foo();
public Supplier<Void> main;
Foo() {
main = new Supplier<Void>() {
Void get() {
...
}
}
}
}
也就是说,实际上没有main
方法。有一个main
领域,在某处深处,里面有一个功能。在我上面的示例中,该函数称为get
. 在 Kotlin 中,它被称为invoke
.
我喜欢这样想。Kotlin 中的方法(即您在指定其行为的对象上定义的东西)本身并不是一流的对象。他们是存在于物体上的二等公民。您可以通过将它们转换为函数来将它们转换为一流的对象。函数是普通对象,就像其他任何对象一样。如果您使用一个普通对象(可能是也可能不是函数)并使用 调用它()
,那么您实际上是在调用.invoke(...)
它的方法。也就是说,()
是真正最终调用方法的对象上的运算符。所以在 Kotlin 中,函数实际上只是具有自定义invoke
和大量语法糖的对象。
您val
定义了一个作为函数的字段。你fun
定义了一个方法。这两个都可以用 调用()
,但只有一个是真正的方法调用;另一个在暗中呼唤.invoke
另一个物体。它们在语法上看起来相同的事实是无关紧要的。
正如那句老话所说,功能是穷人的对象,对象是穷人的功能。
推荐阅读
- macos - AppleScript - 获取每个打开窗口的边界
- node.js - 如何从表单发布到 URL 并使用 Express 从中获取 JSON?
- sql-server - 用于删除当前和未来日期的 SQL 查询?
- unity3d - 如何旋转对象以沿矢量 Unity3D 指向
- python - 将数据添加到 CSV 文件的新列和第一行
- angular - 错误 TS2304:部署云功能 firebase 时找不到名称“元素”
- selenium - NightwatchJS - 手动运行 Selenium 服务器时无法创建会话
- vba - VBA,带工作表,清除表格内容
- spring-boot - Spring Boot @Pattern 自定义消息不起作用
- javascript - Chartist 关于没有 jQuery 的点击功能