对于Scala中的循环 - 评估方式

时间:2018-03-19 12:31:57

标签: scala for-loop optimization

我想打印从1到随机整数的整数(例如,在下面的情况下打印到随机整数<10)。我可以使用例如一个来自以下方式:

1)

val randomNumber=r.nextInt(10)
for (i <- 0 to randomNumber) {println(i)}

2)

for (i <- 0 to r.nextInt(10)) {println(i)}

我的问题如下。计算意义上1)和2)之间有区别吗?很明显,随机数r.nextInt(10)仅计算一次,然后分配给它 在第一种情况下变量randomNumber但第二种情况呢?部分r.nextInt(10)在循环的开始时只计算一次,还是为循环的每次迭代计算?如果是,那么从计算的角度来看,第一个变量更好?我知道这个提议的示例是一个简单的示例,但可能有更复杂的for循环,其中优化可能非常有用。如果第二种情况中的表达式r.nextInt(10)仅计算一次关于例如表达式的表达式i。变量for (i <- 0 to fce(i)) {println(i)}的函数,如this.submitChoice()?我想应该在循环的每次迭代中评估Fce(i)。

感谢您的帮助。 安德鲁

2 个答案:

答案 0 :(得分:2)

不,1)和2)之间没有区别。

for循环的边界将被计算一次,然后for循环将重复这个固定的次数。

比较这两段代码会有很大的不同:

val randomNumber=r.nextInt(10)
for (i <- 0 to 10) {println(randomNumber)}

for (i <- 0 to 10) {println(r.nextInt(10))}

第一个for循环将打印相同值的10倍,第二个将打印10个随机值。

但你仍然可以将第二个重写为

def randomNumber=r.nextInt(10)
for (i <- 0 to 10) {println(randomNumber)}

每次执行循环时,从val到函数的更改都会导致重新评估。

现在,关于

for (i <- 0 to function(i)) {doSomething()}

这不会编译。变量i仅在for循环的{}之间的范围内可用,因此不用于计算循环边界。

我希望这会澄清一些事情!

答案 1 :(得分:1)

这两个版本做同样的事情,看看为什么你需要意识到Scala中的for与其他语言(如C/C++的工作方式有很大不同。

在Scala中,for只是一些语法,可以更轻松地将map/foreachflatMapwithFilter方法链接在一起。它使得功能代码看起来更像命令式代码,但它仍然以功能性方式执行。

所以你的第二块代码

for (i <- 0 to r.nextInt(10)) {println(i)}
编译器将

更改为

(0 to r.nextInt(10)).foreach{ i => println(i) }

以这种方式查看,您可以看到首先计算范围(使用对nextInt的单个调用),然后在该范围内调用foreach。因此,nextInt的调用次数与第一个代码块的次数相同。