web-dev-qa-db-fra.com

Méthode principale dans Scala

J'ai écrit une classe Scala et défini la méthode main(). Elle a compilé, mais quand je l'ai exécutée, j'ai obtenu NoSuchMethodError:main. Dans tous les = scala exemples, j'ai vu, la méthode principale est définie dans un objet. Dans Java nous définissons la méthode principale dans une classe. Est-il possible de définir main() dans une classe Scala ou avons-nous toujours besoin d'un objet pour cela?

33
user2327621

Pour répondre à votre question, jetez un œil à ce qui suit: J'ai créé une classe scala, je l'ai compilée et décompilée, et ce que j'ai obtenu est intéressant.

class MyScalaClass{
   def main(args: Array[String]): Unit = {
         println("Hello from main of class")
   }
}

Compiled from "MyScalaClass.scala"

public class MyScalaClass {
      public void main(Java.lang.String[]);
      public MyScalaClass();
}

Cela signifie donc que lorsque la classe scala est convertie en classe Java alors la méthode principale de la classe scala qui, dans convertit la méthode principale dans Java est pas statique. Et par conséquent, nous ne serions pas en mesure d'exécuter le programme car JVM n'est pas en mesure de trouver le point de départ dans le programme.

Mais si le même code est fait en utilisant le 'objet' mot-clé alors:

Compiling the following:

object MyScalaClass{
 def main(args: Array[String]): Unit = {
  println("Hello from main of object")
 }
}

Decompiling the following:
javap MyScalaClass$.class

Compiled from "MyScalaClass.scala"
public final class MyScalaClass$ {
 public static final MyScalaClass$ MODULE$;
 public static {};
 public void main(Java.lang.String[]);
}

Decompiling the following
javap MyScalaClass.class

Compiled from "MyScalaClass.scala"
public final class MyScalaClass {
  public static void main(Java.lang.String[]);
}

Nous avons donc ici public static void main dans MyScalaClass.class par conséquent, la méthode principale peut être exécutée directement par la machine virtuelle Java ici.

J'espère que vous avez obtenu votre réponse.

54
Apoorv Verma

Comme Eugene l'a dit dans un commentaire, il n'y a pas de méthodes statiques dans Scala. Mais regardez ceci:

$ cat Echo.scala
object Echo {
  def main( args:Array[String] ):Unit = args foreach println
}

$ scalac Echo.scala

$ javap Echo\$.class
Compiled from "Echo.scala"
public final class Echo$ {
  public static final Echo$ MODULE$;
  public static {};
  public void main(Java.lang.String[]);
}

$ javap Echo.class
Compiled from "Echo.scala"
public final class Echo {
  public static void main(Java.lang.String[]);
}

Notez que le fichier de classe pour la classe Echo (pas Echo $, l'objet) a en effet une méthode principale publique void statique. Scala génère des méthodes statiques pour les méthodes définies dans les objets pour la compatibilité avec Java.

Cependant, je considère la création d'une méthode principale dans un programme Scala anachronisme. Utilisez plutôt le trait App; c'est plus propre:

object Echo extends App {
  args foreach println
}
19
AmigoNico

Lorsque je veux tester mon code dans une idée intelligente scala, je crée simplement un objet compagnon juste en dessous de ma classe et y mets une méthode principale. C'est tout. Voir un exemple:

class Colon {
    class Cow {
        def ^ (moon:Moon): Unit ={
        println("Cow jumped over the moon")
        }
    }
    class Moon{
        def ^:(cow:Cow) = println("This cow jumped over moon too")
    }
}
object Colon{
    def main(args: Array[String]): Unit = {
    val c:Colon = new Colon
    val cow = new c.Cow
    val moon = new c.Moon
    cow ^ moon
    cow ^: moon
    moon.^:(cow)
    }
}
3
abshar