Kotlin允许我创建两个main()函数。但是不允许两个myfun()函数。
Test1.kt:
package start
fun main(args: Array<String>) {
}
fun myfun(args: Array<String>) {
}
Test2.kt:
package start
// OK!
fun main(args: Array<String>) {
}
// Error! Conflicting overloads
fun myfun(args: Array<String>) {
}
答案 0 :(得分:8)
由于实际原因,Kotlin允许在同一个包中拥有多个顶级main
函数 - 这样一个人可以在每个文件中都有一个入口点,而无需将这些文件移动到不同的包中。
这是可能的,因为具有顶级成员的每个.kt文件都被编译为相应的类文件,因此这些main
函数不会发生冲突,因为它们位于单独的类文件中。
为什么允许main
函数而不允许其他顶级函数?在同一个包中具有相同名称和签名的多个函数将使得在从Kotlin调用时无法区分它们。这不是main
函数的问题,因为当它用作程序的入口点时,需要指定它所在的类名。
答案 1 :(得分:6)
main()有什么特别之处?还有其他特殊功能吗?
启动您需要的Java程序
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所述,此行为在过去更为严格:Why does Kotlin lang allow only single main function in project?
答案 2 :(得分:6)
关于如何使用文件范围函数的问题,默认情况下,顶级函数(未在类中声明的函数)是public
,这意味着它们的签名必须是唯一的,包括包名。您可以通过在private
修饰符前添加private fun myfun(args: Array<String>) {
// method body here
}
修饰符(例如,在每个文件中)为函数而不是包创建函数:
private val handleButtonClick = View.OnClickListener { view->
Log.d("my_tag", "click!")
}