main和regular函数有什么区别?

Kotlin允许我创建两个main()函数。 但是不允许两个myfun()函数。

  • main()有什么特别之处? 还有其他特殊function吗?
  • 我可以在同一个包中创建两个静态myfun()函数吗? 我希望他们有像主要文件范围。

Test1.kt:

package start fun main(args: Array) { } fun myfun(args: Array) { } 

Test2.kt:

 package start // OK! fun main(args: Array) { } // Error! Conflicting overloads fun myfun(args: Array) { } 

由于实际的原因,Kotlin允许在同一个包中包含多个顶级main函数 – 这样,每个文件都可以有一个入口点,而不必将这些文件移动到不同的包中。

这是可能的,因为每个带有顶级成员的.kt文件都被编译成相应的类文件,所以这些main函数不会发生冲突,因为它们位于不同的类文件中。

为什么它允许mainfunction,而不是其他的顶级function? 在同一个包中有多个具有相同名称和签名的函数将使得从Kotlin调用时无法区分它们。 这对main函数来说不是问题,因为当它被用作程序的入口点时,需要指定它所在的类名。

main()有什么特别之处? 还有其他特殊function吗?

开始你需要的Java程序

  1. 一个类文件,
  2. 该类文件中的static void main(String[])方法。

所以从包装外面你可以启动任何这些main方法。

但是,如果您尝试从包内的另一个Kotlin文件调用main方法,则会出现错误,因为Kotlin无法消除另一个方法的歧义。

您可以随意从Java中调用它们中的任何一个,因为它们是用不同的类文件编译的(请参阅下文)。

我可以在同一个包中创建两个静态myfun()函数吗?

你不能在Kotlin的同一个包中定义两个同名的顶级方法(有上述例外)。

这是你的代码编译到:

 public final class Test1Kt { public static final void main(@NotNull String[] args) { /* ... */ } public static final void myFun(@NotNull String[] args) { /* ... */ } } public final class Test2Kt { public static final void main(@NotNull String[] args) { /* ... */ } public static final void myFun(@NotNull String[] args) { /* ... */ } } 

就JVM而言,所有这些方法都可以和平共处。 但是这是Kotlin的实现细节

让我们忘记Kotlin应用程序在JVM上运行的第二步。 假装你唯一的工具是Kotlin,你不能使用Java,也许你正在编写一个Kotlin跨平台的模块。 你怎么能有两个同名的顶级函数? 你将如何选择哪一个打电话? 再一次,你会得到一个错误,因为Kotlin不能消除另一个方法的歧义。

编辑:正如@Todd指出的那样,这个行为在过去更加严格: 为什么Kotlin lang只允许在项目中使用单个主函数?

关于如何具有文件范围函数的问题,默认情况下,顶级函数(没有在类中声明的)是public ,这意味着它们的签名必须是唯一的,包括包名称。 你可以在函数中使用本地函数,而不是使用private修饰符,例如在每个文件中加上前缀:

 private fun myfun(args: Array) { // method body here }