Question

Je suis tout à fait nouveau pour le langage de programmation Scala, et a essayé quelque chose stucked dans mon esprit pendant que je suivais les notes de cours à ici .

Je pense que je ne pouvais pas vraiment comprendre comment opérateur contre les travaux, voici quelques choses que j'essayées:

J'ai créé un générateur de nombres pseudo-aléatoires, puis essayé de créer une liste d'une valeur aléatoire:

scala> val gen = new java.util.Random
gen: java.util.Random = java.util.Random@1b27332

scala> gen nextInt 3 :: Nil
<console>:7: error: type mismatch;
 found   : List[Int]
 required: Int
       gen nextInt 3 :: Nil
                     ^

Mais il a essayé de passer la liste (3) à la méthode nextnt. Quand je paratheses, il n'y avait pas de problème

scala> (gen nextInt 3) :: Nil
res69: List[Int] = List(1)

J'étais curieux de connaître l'ordre d'exécution, donc je créé une fonction pour vérifier

scala> def pr(i:Int):Int = { println(i); i }
pr: (i: Int)Int

scala> pr(1) :: pr(2) :: pr(3) :: Nil
1
2
3
res71: List[Int] = List(1, 2, 3)

Comme on le voit dans les sorties, l'ordre d'exécution est le même que l'ordre d'apparition. Ensuite, je pensais que ce serait peut-être au sujet de la fonction « nextInt », puis j'ai essayé suivante:

scala> 1 + 2 :: Nil
res72: List[Int] = List(3)

Il a d'abord exécuté plus, et après que le contre est exécuté. Voici donc la question: Quelle est la différence entre gen nextInt 3 :: Nil et 1 + 2 :: Nil

Était-ce utile?

La solution

Il y a deux choses préoccupantes ici: priorité et fixité . Comme sepp2k mentionné, cette question sur Stack Overflow explique la priorité, la pensée des règles, cité, ne sont pas assez complètes, et il y avait de très petits changements de Scala 2.7 à 2.8 Scala. Les différences concernent la plupart des opérateurs se terminant en =, cependant.

pour fixité , presque tout à Scala est lu de gauche à droite, ce qui est ce que les programmeurs sont habitués. En Scala, cependant, les opérateurs se terminant en : sont lues de droite à gauche.

Prenez donc cet exemple:

1 + 2 :: Nil

Tout d'abord, la priorité. Ce qui a le plus prioritaire, + ou :? Selon le tableau, + a préséance sur :, de sorte que l'addition est fait en premier. Par conséquent, l'expression est égale à ceci:

((1).+(2)) :: Nil

Maintenant, il n'y a pas de conflit de priorité, mais depuis les extrémités de :: dans :, il a une fixité diferent. Il est lu de droite à gauche, donc:

Nil.::((1).+(2))

D'autre part, en ceci:

gen nextInt 3 :: Nil

Le :: opérateur a priorité sur nextInt, parce que : a préséance sur toutes les lettres. Par conséquent, et en se rappelant sa fixité, il devient:

gen nextInt Nil.::(3)

Ce qui devient alors

gen.nextInt(Nil.::(3))

A quel point l'erreur est évidente.

PS: J'écris (1).+(2) au lieu de 1.+(2) parce que, au moment où nous écrivons ces lignes, 1. est interprété comme un nombre double, ce qui 1.+(2) une expression infixe ajoutant la double 1,0 à 2. Cette syntaxe est obsolète depuis Scala 2.10 .0, et ne sera probablement pas présent sur Scala 2,11.

Autres conseils

Il est sur la priorité de ne pas l'ordre d'exécution. + a une priorité supérieure ::, donc Parsis de a + b :: c comme (a + b) :: c. Cependant les appels de méthode infix avec des noms réguliers ont une priorité plus faible, de sorte Parsis de a foo b c comme a foo (b c).

Voir cette question pour une liste des opérateurs classés par leur ordre de priorité dans scala.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top