7
votes

Qu'est-ce que cela signifie quand j'utilise def pour définir un champ à Scala?

Quelle est exactement la différence entre: xxx

et xxx

semble que dans les deux cas, je me retrouve avec une variable < Code> FOO que je peux me référer à Sans parenthèses, toujours évaluer à 5 .


0 commentaires

5 Réponses :


4
votes

Qu'est-ce que cela signifie quand j'utilise def pour définir un champ à Scala

Vous ne pouvez pas définir un champ à l'aide de def .

semble que dans les deux cas, je me retrouve avec une variable FOO que je peux me référer à Sans parenthèse, toujours en évaluant à 5.

Non, dans les deux cas, vous vous retrouvez avec une méthode foo , que vous pouvez appeler sans parenthèses.

pour voir Vous pouvez utiliser javap : xxx

Cependant, voir http://tommy.chheng.com/index.php/2010/03 / quand des méthodes à appeler - avec-ou-sans-parenthèses-in-scala /


0 commentaires

17
votes

Vous ne définissez pas une variable dans les deux cas. Vous définissez une méthode. La première méthode n'a pas de liste de paramètres, la seconde dispose d'une liste de paramètres, qui est vide. Le premier devrait être appelé comme celui-ci xxx

tandis que la seconde doit être appelée comme ceci xxx

Cependant, le compilateur Scala vous permettra d'appeler des méthodes avec un vide Liste des paramètres sans parenthèses, la simple forme d'appel fonctionnera pour la deuxième méthode. Les méthodes sans paramètres ne peuvent pas être appelées avec les parenthèses

Le style Scala préféré consiste à définir et à appeler des méthodes sans argument qui ont des effets secondaires avec les parenthèses. Les méthodes sans argument sans effets secondaires doivent être définies et appelées sans les parenthèses.

Si vous définissez une variable, la syntaxe est xxx


1 commentaires

En réalité, SCALA vous permettra d'élier n'importe quel nombre de listes de paramètres vides (suivi)! Essayez def x () () () () () () () () () = 5 !



7
votes

Avant toute autre chose est dit, def ne définit pas de champ, il définit une méthode.

Dans le second cas, vous pouvez omettre des parenthèses en raison d'une caractéristique spécifique de Scala. Il y a deux différences d'intérêt ici: une mécanique et une utilisation recommandée.

Commencer avec ce dernier, il est recommandé d'utiliser une liste de paramètres vide lorsqu'il y a des effets secondaires. Un exemple classique est fermeture () . Vous omettez des parenthèses s'il n'y a pas d'effets secondaires pour appeler l'élément.

Maintenant, en tant que différence pratique - au-delà de possibles mélanges syntaxiques étranges dans des cas d'angle (je ne dis pas qu'il y ait, il suffit de conjecturer) - des types de structure doivent suivre la convention correcte.

Par exemple, source avait un Fermer la méthode sans parenthèse, ce qui signifie un type structurel de def fermeture (): unité n'accepterait pas < code> source . De même, si je définis une méthode structurelle que défaire de défile: unité , alors java observe Les objets ne seront pas acceptés.


0 commentaires

4
votes

En outre aux réponses déjà données, j'aimerais souligner deux points:

  • La possibilité de définir des méthodes sans paramètre est un moyen de réaliser le Principe d'accès uniforme . Cela permet de cacher la différence entre les champs et les méthodes, ce qui facilite la mise en œuvre ultérieure.

  • Vous pouvez appeler une méthode définie comme def fio () = 5 à l'aide de FOO , mais vous ne peut pas appeler un Méthode définie comme def foo = 5 en utilisant foo ()


0 commentaires

0
votes

Je suis surpris que personne ne mentionne quoi que ce soit sur la différence de paresse. Tandis que Val code> est évalué une seule fois au moment de la définition, def code> est évalué uniquement lorsque nous l'accédez et que nous l'avons évalué à chaque fois. Voir l'exemple ci-dessous:

scala> def foo = {
     | println("hi")
     | 5
     | }
foo: Int

scala> val onlyOnce = foo
scala> def everyTime = foo

scala> onlyOnce
res0: Int = 5
scala> onlyOnce
res1: Int = 5

scala> everyTime
hi
res2: Int = 5
scala> everyTime
hi
res3: Int = 5


0 commentaires