我想在Scala中实现Repeat Until。
注释代码将抛出StackOverflowException。
但现在代码在main方法中运行。
但我不知道为什么以及这两个片段之间的区别是什么。
object REPEAT{
class REPEAT(command: => Unit){
def UNTIL(cond: => Boolean):Unit = {
command
if(!cond) UNTIL(cond)
}
}
def REPEAT(command: => Unit): REPEAT = {
new REPEAT(command)
}
def main(args: Array[String]) {
/* this code work well */
var i = 0
REPEAT { i+= 1; println(i)} UNTIL (i == 100)
/*
// something wrong in this code.
var i = 0
new REPEAT {
i += 1; println(i)
} UNTIL (i == 100)
*/
}
}
ps:我发现错误的代码只是将var i更改为1但不再改变它。
错误的代码输出:
1
线程中的异常" main" java.lang.StackOverflowError at REPEAT $$不久$ 1 $$ anonfun $$ lessinit $更大$ 1.适用$ MCV $ SP(REPEAT.scala:15) 在REPEAT $ REPEAT.UNTIL(REPEAT.scala:4)
答案 0 :(得分:4)
这就是问题所在:
new REPEAT {
i += 1; println(i)
} UNTIL (i == 100)
相当于:
new REPEAT() {
i += 1; println(i)
} UNTIL (i == 100)
因此,您实际上在构造函数中创建了REPEAT
类command = ()
和i += 1; println(i)
的新实例 - 所以i++
只重复一次并重复()
无限。
正确的称呼方式:
new REPEAT({
i += 1; println(i)
}) UNTIL (i == 100)
原因是您不必在scala中明确指定Unit
类型的单个参数:
scala> class Aaaa(a: Unit)
defined class Aaaa
scala> new Aaaa //parenthesis is not required for 'new'
res10: Aaaa = Aaaa@17de44d4
scala> def aaaa(a: Unit) = 5
aaaa: (a: Unit)Int
scala> aaaa()
res13: Int = 5