main和regular函数有什么区别?

时间:2018-01-14 01:54:22

标签: kotlin

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

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

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>) {
}

3 个答案:

答案 0 :(得分:8)

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

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

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

答案 1 :(得分:6)

  

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

启动您需要的Java程序

  1. 一个类文件,
  2. 该类文件中的
  3. static void main(String[])方法。
  4. 因此,从软件包外部您可以启动任何这些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!")
}