Différence entre l'utilisation du trait App et de la méthode principale dans Scala


87

Quelle est la différence entre

object Application extends App {
   println("Hello World")
}

et

object Application {
    def main(args: Array[String]): Unit = {
        println("Hello World");
    }
}


1
Dans le cas des travaux Apache Spark, la documentation indique "que les applications doivent définir une méthode main () au lieu d'étendre scala.App. Les sous-classes de scala.App peuvent ne pas fonctionner correctement."
leo9r

Réponses:


64

Le trait App est un moyen pratique de créer un programme exécutable scala. La différence avec l'alternative de la méthode principale est (à part les différences syntaxiques évidentes) que le trait App utilise la fonction d'initialisation retardée.

À partir des notes de version de la version 2.9 (voir http://www.scala-lang.org/old/node/9483 )

Les objets héritant du trait App utilisent à la place la fonction d'initialisation retardée de Scala 2.9 pour exécuter tout le corps dans le cadre d'une méthode principale héritée.

Une autre nouvelle fonctionnalité du schéma App est que les arguments de ligne de commande sont désormais accessibles via la valeur args (qui est héritée du trait App)


Suis - je bien entendu que sans le bénéfice du trait App, cet objet (Application) n'a pas d' agir comme tout autre objet scala - en ce que le point d'entrée est la mainméthode et le corps n'est pas exécuté comme prévu. Est-il exécuté du tout à un moment donné après l'entrée dans main?
Richard Sitze

@RichardSitze Il y a une mainméthode dans le Apptrait qui est mélangée à votre Applicationobjet. Il n'y a pas de magie au-delà du fait que l'initialisation retardée est ce qui exécute le corps de votre Applicationobjet.
Emil H

4

Ces deux cas ne sont pas les mêmes sur le script scala.

object extends Appn'a pas été exécuté par la scala MyObject.scalacommande " ", mais l'objet contenant la méthode principale a été exécuté par la scala MyObject.scalacommande " ". Ce qui a été décrit comme scala recherchant un objet avec la méthode principale de script.

Lorsque vous utilisez REPL ou scala workseet d'Eclipse, vous devez appeler MyObject.main(Array[String]())explicitement dans les deux cas.

Cette astuce simple sera utile pour les débutants comme moi.


0

Le trait d'application est implémenté à l'aide de la fonctionnalité [[DelayedInit]], ce qui signifie que les champs de l'objet n'auront pas été initialisés avant que la méthode principale n'ait été exécutée.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.