54 votes

pour les expressions rapport foreach en Scala

Je suis en train de travailler mon chemin à travers la Programmation Scala, et même si je suis tenté de regarder les choses du point de vue de Python, je ne veux pas de programme "Python en Scala."

Je ne suis pas tout à fait sûr de quoi faire dans la mesure du contrôle de flux de passe: en Python, nous utilisons for x in some_iterable à la mort, et nous l'aimons. Très semblable à la construction existe dans Scala qui Odersky appelle une pour l'expression, sans doute pour la distinguer de la Java pour la boucle. Aussi, Scala a un foreach d'attribut (je suppose que ce serait un attribut, je ne sais pas assez sur la Scala de nom correctement) pour itérable types de données. Il ne semble pas comme je peux l'utiliser foreach de faire beaucoup plus que d'appeler une fonction pour chaque élément dans le conteneur.

Cela me laisse avec quelques questions. Tout d'abord, sont des expressions important/très utilisé constructions en Scala comme ils sont en Python, et deuxièmement, quand dois-je utiliser foreach au lieu d'une expression (autres que le cas évident de l'appel d'une fonction sur chaque élément d'un conteneur)?

J'espère que je ne suis pas en train terriblement ambigu ou trop large, mais je suis juste essayer d'analyser une partie de la conception de la langue/fondamentaux de la Scala (qui semble très cool à ce jour).

59voto

huynhjl Points 26045

python utilise for dans les interprétations de la liste et le générateur d'expressions. Ceux-ci sont très semblables à la scala for expression:

c'est python

>>> letters = ['a', 'b', 'c', 'd']
>>> ints = [0, 1, 2, 3]
>>> [l + str(i) for l in letters for i in ints if i % 2 == 0]
['a0', 'a2', 'b0', 'b2', 'c0', 'c2', 'd0', 'd2']

c'est scala

scala> val letters = List('a', 'b', 'c', 'd')
scala> val ints = List(0, 1, 2, 3)
scala> for (l <- letters; i <- ints if i % 2 == 0) yield l.toString + i
res0: List[java.lang.String] = List(a0, a2, b0, b2, c0, c2, d0, d2)

Chaque construction peut prendre un certain nombre de générateurs/itérateurs, appliquer des filtres d'expressions et de donner une expression combinée. En python l' (expr for v1 in gen1 if expr1 for v2 in gen2 if expr2) est à peu près équivalent à:

for v1 in gen1:
  if expr1:
    for v2 in gen2:
      if expr2:
        yield expr

En scala for (v1 <- gen1 if expr1; v2 <- gen2 if expr2) yield expr est à peu près équivalent à:

gen1.withFilter(expr1).flatMap(v1 => gen2.withFilter(expr2).map(v2 => expr))

Si vous aimez le python for x in xs de la syntaxe, vous aurez probablement l'amour de la scala for expression.

Scala a d'autres syntaxe et traduction de rebondissements. La syntaxe de sage - for peut être utilisé avec des accolades, de sorte que vous pouvez mettre des déclarations sur des lignes séparées. Vous pouvez également effectuer des affectations de valeur.

val res = for {
    i <- 1 to 20; i2 = i*i
    j <- 1 to 20; j2 = j*j
    k <- 1 to 20; k2 = k*k
    if i2 + j2 == k2
  } yield (i, j, k)

Aussi v1 <- gen1 vraiment effectue une correspondance case v1 => gen1. Si aucune correspondance n'est trouvée ces éléments sont ignorés de l'itération.

scala> val list = List(Some(1), None, Some(2))
scala> for (Some(i) <- list) yield i
res2: List[Int] = List(1, 2)

Je pense que for a une place importante dans la langue. Je peux dire à partir de la réalité, il existe un chapitre entier (23) à ce sujet dans le livre que vous êtes en train de lire!

25voto

Daniel C. Sobral Points 159554

Oui, Scala pour des compréhensions (comme ils sont communément connus) sont beaucoup utilisés, mais ils sont vraiment simplement sucre syntaxique pour une combinaison particulière de méthodes, et beaucoup préfèrent appeler ces méthodes directement au lieu d'utiliser du sucre syntaxique.

Pour mieux comprendre la Scala pour des compréhensions, veuillez vous référer à cette question. En particulier, vous verrez qu' for (x <- xs) f(x) est la même chose que xs.foreach(x => f(x)).

Maintenant, vous mentionnez que vous ne semblez pas beaucoup d'utilisation avec foreach méthode, mais je vais souligner que presque toutes les méthodes de la Scala de collections sont (ou peuvent être) mis en œuvre avec juste foreach. Voir la documentation de l' Traversable -- toutes ses méthodes peuvent être mises en œuvre avec seulement foreach.

Notez que Scala yield ne ressemble en rien à Python yield -- vous pouvez vérifier que la question de trop.

3voto

Fabian Steeg Points 24261

Avec son support pour imbriquée itération, les filtres, et de la transformation, je dirais Scala for est l'un des points forts de la langue et très central. J'ai tendance à le favoriser par rapport à l'aide foreach, map et filter.

3voto

JOTN Points 4165

Le foreach est un style fonctionnel tout en la pour est un impératif de style. Si vous avez déjà fait de lisp ou scheme, vous êtes déjà familier avec la programmation fonctionnelle. Si vous n'avez pas le cas, alors il pourrait être un peu déroutant au premier abord. La première chose que je voudrais faire est de lire sur la fermeture de la syntaxe, qui sont des fonctions anonymes vous passez dans des choses comme foreach. Une fois que vous comprenez que ça va faire plus de sens.

3voto

Northover Points 838

Vos questions sont largement répondu par ce qui suit:

Scala Pour des Compréhensions

Scala Rendement

Pour summaraize: C'est en grande partie stylistique. Personnellement, je préfère la méthode fonctionnelle, mais je préfère la concision de compréhensions lorsque vous traitez avec des boucles imbriquées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X