random
random

Reputation: 4038

What is the difference between main and regular function?

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

Answers (3)

Ilya
Ilya

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

Joe Sewell
Joe Sewell

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

Eugen Pechanec
Eugen Pechanec

Reputation: 38223

What is special about main()? Are there other special functions?

To start a Java program you need

  1. a class file,
  2. 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

Related Questions