Reputation: 4038
Kotlin allows me to create two main() functions. But does not allow two myfun() functions.
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>) {
}
Upvotes: 12
Views: 1335
Reputation: 23125
Kotlin allows to have multiple top-level main
functions in the same package due to practical reasons — so that one could have an entry point in an each file without moving these files to different packages.
It is possible because each .kt file with top-level members is compiled to the corresponding class file, so these main
functions do not clash, because they are located in separate class files.
Why is it allowed for main
functions and not for other top-level functions? Having multiple functions with the same name and signature in the same package would make it impossible to distinguish them when calling from Kotlin. This is not a problem for main
function, because when it is used as an entry point for a program, it's required to specify the class name where it is located.
Upvotes: 8
Reputation: 6620
Regarding the question about how to have file-scoped functions, by default top-level functions (those not declared within a class) are public
, which means their signatures must be unique, including the package name. You can make functions local to the file, rather than the package, by prefixing them with the private
modifier, e.g., in each file:
private fun myfun(args: Array<String>) {
// method body here
}
Upvotes: 6
Reputation: 38223
What is special about main()? Are there other special functions?
To start a Java program you need
static void main(String[])
method in that class file. So from outside of the package you'd be able to start any of these main
methods.
However if you try to call the main
method from another Kotlin file inside of the package, you'd get an error, because Kotlin can't disambiguate one method from the other.
You can call any of them from Java as you please because they're compiled in different class files (see further).
Can I create two static myfun() functions in same package?
You can't define two top-level methods with the same name in the same package in Kotlin (with the above exception).
This is what your code compiles to:
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) { /* ... */ }
}
As far as JVM is concerned all of these methods could coexist in peace. But this is an implementation detail of Kotlin.
Let's forget for a second that Kotlin apps run on JVM. Pretend your only tool is Kotlin, and you can't use Java, perhaps you're writing a Kotlin cross-platform module. How could you have two top-level functions with the same name? How would you pick which one to call? Again, you'd get an error, because Kotlin couldn't disambiguate one method from the other.
Edit: As noted by @Todd this behavior has been even more strict in the past: Why does Kotlin lang allow only single main function in project?
Upvotes: 6