在Scala中实现REPEAT UNTIL时的stackoverflow

时间:2014-11-29 08:01:03

标签: java scala

我想在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)

1 个答案:

答案 0 :(得分:4)

这就是问题所在:

   new REPEAT {
            i += 1; println(i)
   } UNTIL (i == 100)

相当于:

   new REPEAT() {
            i += 1; println(i)
   } UNTIL (i == 100)

因此,您实际上在构造函数中创建了REPEATcommand = ()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