我想打印从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)。
感谢您的帮助。 安德鲁
答案 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/foreach
,flatMap
和withFilter
方法链接在一起。它使得功能代码看起来更像命令式代码,但它仍然以功能性方式执行。
所以你的第二块代码
for (i <- 0 to r.nextInt(10)) {println(i)}
编译器将更改为
(0 to r.nextInt(10)).foreach{ i => println(i) }
以这种方式查看,您可以看到首先计算范围(使用对nextInt
的单个调用),然后在该范围内调用foreach
。因此,nextInt
的调用次数与第一个代码块的次数相同。