scala for/yield 循环 vs java for 循环(初始标题 "recursive value XXX needs type",尽管类型已经说明)

scala for/yield loop vs java for loop (initial title "recursive value XXX needs type", despite type already stated)

我是 Scala 的新手。要温柔。我想在 scala 中使用 for/yield 做一些非常基本的事情。 Java:

中这段代码的等价物是什么
int somme = 0
for (int i = 1; i < 11 ; i++ ) 
    somme = somme + i

在 Scala 中?

var somme: Int = 0    
for {
  i <- 1 to 10
  somme = somme  + i
} yield somme

我在 scala 中遇到的错误是:

"recursive value somme needs type"

但类型已定义!它是一个整数!

在 scala 中使用 var 不是一个好主意,因为它是可变的。

您可以轻松做到这一点:

  val somme = (1 to 10).sum

但是如果你真的想使用 var 并理解它:

var somme: Int = 0
  for {
    i <- 1 to 10
  } yield {
    somme = somme + i
  }
println(somme)

您不需要使用 yield。等价物可能是这样的:

var somme: Int = 0    

for(i <- 1 to 10 ){
  somme = somme + i
}

for 在 Scala 中是 foreachmapflatMapwithFilter 的语法糖。真的一点都不循环

for without yieldforeach 的语法糖,因此 大致等同于 Java "enhanced" for (var el : collection) 循环。

相当于 Scala 中的 Java for 循环实际上是 while 循环,因为这是 Scala 唯一的循环类型:

var somme = 0
var i = 1

while (i < 11) { 
  somme += i
  i += 1
}

或者,也可以写成尾递归:

@scala.annotation.tailrec
def doIt(somme: Int = 0, i: Int = 1): Int = 
  if (i < 11) doIt(somme + i, i + 1) else somme

doIt()
//=> res: Int = 55

如果你真的想使用for-comprehension,你需要使用不带yield的版本,相当于Java增强的for循环:

var somme = 0
for { i ← 1 to 10 } somme += i

这是

的语法糖
var somme = 0
(1 to 10) foreach { i ⇒ somme += i }

大致相当于下面的Java代码:

var somme = 0;
for (var i : java.util.stream.IntStream.range(1, 11)) somme += i;

但是请注意,这 不是 在 Scala 中(或者实际上在现代 Java 中)编写代码的方式。在 Scala 中,在 general 情况下,您将使用这样的折叠:

(1 to 10) reduce {_ + _}
//=> res: Int = 55

在这个具体案例中:

(1 to 10).sum
//=> res: Int = 55

这等同于现代语言的写法 Java:

java.util.stream.IntStream.range(1, 11).reduce((a, b) -> a + b)

java.util.stream.IntStream.range(1, 11).sum()