for 表达式与 Scala 中的 foreach

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4466362/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:39:47  来源:igfitidea点击:

for expressions versus foreach in Scala

scalaloopsforeach

提问by Rafe Kettler

I'm working my way through Programming in Scala, and though I'm tempted to look at things from the perspective of Python, I don't want to program "Python in Scala."

我正在学习Scala 编程,虽然我很想从 Python 的角度看待事物,但我不想编写“Python in Scala”。

I'm not quite sure what to do as far as control flow goes: in Python, we use for x in some_iterableto death, and we love it. A very similar construct exists in Scala which Odersky calls a for expression, probably to distinguish it from the Java for loop. Also, Scala has a foreachattribute (I guess it would be an attribute, I don't know enough about Scala to name it correctly) for iterable data types. It doesn't seem like I can use foreachto do much more than call one function for each item in the container, though.

就控制流而言,我不太确定该做什么:在 Python 中,我们习惯于for x in some_iterable死亡,我们喜欢它。Scala 中存在一个非常相似的构造,Odersky 将其称为 for表达式,可能是为了将其与 Java 的 for 循环区分开来。此外,Scala 有一个foreach用于可迭代数据类型的属性(我猜这将是一个属性,我对 Scala 的了解不够,无法正确命名)。不过,似乎foreach除了为容器中的每个项目调用一个函数之外,我还可以做更多的事情。

This leaves me with a few questions. First, are for expressions important/heavily used constructs in Scala like they are in Python, and second, when should I use foreachinstead of a for expression (other than the obvious case of calling a function on each item of a container)?

这给我留下了几个问题。首先,for 表达式在 Scala 中是否像在 Python 中一样重要/频繁使用,其次,我什么时候应该使用foreach代替 for 表达式(除了在容器的每个项目上调用函数的明显情况)?

I hope I'm not being terribly ambiguous or overbroad, but I'm just trying to grok some of the design/language fundamentals in Scala (which seems very cool so far).

我希望我不是非常模棱两可或过于宽泛,但我只是想了解 Scala 中的一些设计/语言基础知识(到目前为止看起来很酷)。

回答by huynhjl

python uses forin list comprehensions and generator expressions. Those are verysimilar to the scala forexpression:

python 用于for列表推导式和生成器表达式。这些与 scala表达式非常相似for

this is 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']

this is 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)

Each construct can take a number of generators/iterators, apply filters expressions and yield a combined expression. In python the (expr for v1 in gen1 if expr1 for v2 in gen2 if expr2)is roughly equivalent to:

每个构造都可以采用多个生成器/迭代器,应用过滤器表达式并产生组合表达式。在python(expr for v1 in gen1 if expr1 for v2 in gen2 if expr2)中大致相当于:

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

In scala for (v1 <- gen1 if expr1; v2 <- gen2 if expr2) yield expris roughly equivalent to:

在 scalafor (v1 <- gen1 if expr1; v2 <- gen2 if expr2) yield expr中大致相当于:

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

If you love the python for x in xssyntax, you'll likely love the scala forexpression.

如果您喜欢 pythonfor x in xs语法,您可能会喜欢 scalafor表达式。

Scala has some additional syntax and translation twists. Syntax wise forcan be used with braces so that you can put statements on separate lines. You can also perform value assignments.

Scala 有一些额外的语法和翻译技巧。语法明智for可以与大括号一起使用,以便您可以将语句放在单独的行上。您还可以执行值分配。

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)

Also v1 <- gen1really performs a match case v1 => gen1. If there is no match those elements are ignored from the iteration.

v1 <- gen1真是演一场比赛case v1 => gen1。如果没有匹配项,则迭代中将忽略这些元素。

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

I think forhas an important place in the language. I can tell from the fact there is a whole chapter (23) about it in the book you're reading!

我认为for在语言中占有重要地位。我可以从你正在阅读的书中有一整章(23)关于它的事实看出!

回答by Daniel C. Sobral

Yes, Scala for comprehensions (as they are commonly known) are used a lot, but they are really just syntactic sugar for a particular combination of methods, and many prefer to call these methods directly instead of using the syntactic sugar.

是的,用于推导的 Scala(众所周知)被大量使用,但它们实际上只是特定方法组合的语法糖,许多人更喜欢直接调用这些方法而不是使用语法糖。

To better understand Scala for comprehensions, please refer to this question. In particular, you'll see that for (x <- xs) f(x)is the same thing as xs.foreach(x => f(x)).

为了更好地理解 Scala 以进行推导,请参阅此问题。特别是,您会看到这for (x <- xs) f(x)xs.foreach(x => f(x)).

Now, you mention that you don't seem much use with foreachmethod, but I'll point out that almost all of the methods of Scala collections are (or can be) implemented with just foreach. See the documentation for Traversable-- all of its methods can be implemented with only foreach.

现在,您提到您似乎不太会使用foreach方法,但我要指出的是,几乎所有 Scala 集合的方法都(或可以)仅使用foreach. 请参阅文档Traversable- 它的所有方法都可以仅使用foreach.

Note that Scala's yieldbears no resemblance to Python's yield-- you can look up thatquestion too.

请注意,Scalayield与 Python 没有相似之处yield——您也可以查找问题。

回答by Fabian Steeg

With its support for nested iteration, filters, and transformation, I'd say Scala's foris one of the strong points of the language and very central. I tend to favor it over using foreach, mapand filter.

凭借对嵌套迭代、过滤器和转换的支持,我认为 Scalafor是该语言的强项之一,并且非常重要。我倾向于使用它而不是使用foreach,mapfilter

回答by JOTN

The foreach is a functional style while the for is an imperative style. If you've ever done any lisp or scheme, you're already familiar with functional programming. If you haven't then it might be a bit confusing at first. The first thing I would do is read up on the closure syntax which are anonymous functions you pass into things like foreach. Once you understand that it will all make more sense.

foreach 是一种函数式风格,而 for 是一种命令式风格。如果您曾经做过任何 lisp 或方案,那么您就已经熟悉函数式编程。如果你还没有,那么一开始可能会有点混乱。我要做的第一件事是阅读闭包语法,这是您传递给诸如 foreach 之类的匿名函数。一旦你明白这一切都会变得更有意义。

回答by Northover

Your questions are largely answered by the following:

您的问题主要通过以下方式回答:

Scala's For Comprehensions

Scala 的理解

Scala Yield

Scala 产量

To summaraize: It's largely stylistic. Personally, I favor the functional methodology, but prefer the succinctness of comprehensions when dealing with nested loops.

总结一下:它主要是风格化的。就我个人而言,我更喜欢函数式方法论,但在处理嵌套循环时更喜欢推导式的简洁性。