Java 机具重复时堆栈溢出,直到在Scala中

Java 机具重复时堆栈溢出,直到在Scala中,java,scala,Java,Scala,我想在Scala中实现一个Repeat-Until 注释代码将抛出StackOverflowException 但是代码现在在main方法中运行 但我不知道为什么,这两个片段之间有什么区别 object REPEAT{ class REPEAT(command: => Unit){ def UNTIL(cond: => Boolean):Unit = { command if(!cond) UNTIL(cond)

我想在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:我发现了错误的代码,只需将VARI更改为1,但不要再更改它

错误代码的输出:

一,

线程“main”java.lang.StackOverflower中的异常位于 重复$$anon$1$$anonfun$$lessinit$大于$1。应用$mcV$sp(重复。scala:15) 在REPEAT$REPEAT.UNTIL时(REPEAT.scala:4)

这就是问题所在:

   new REPEAT {
            i += 1; println(i)
   } UNTIL (i == 100)
相当于:

   new REPEAT() {
            i += 1; println(i)
   } UNTIL (i == 100)
因此,实际上您正在使用
command=()
i+=1创建
REPEAT
类的新实例;println(i)
在构造函数中-因此
i++
只重复一次,而
()
则无限重复

正确的称呼方式是:

    new REPEAT({
            i += 1; println(i)
    }) UNTIL (i == 100)
原因是您不必在scala中使用
Unit
type显式指定单个参数:

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
这就是问题所在:

   new REPEAT {
            i += 1; println(i)
   } UNTIL (i == 100)
相当于:

   new REPEAT() {
            i += 1; println(i)
   } UNTIL (i == 100)
因此,实际上您正在使用
command=()
i+=1创建
REPEAT
类的新实例;println(i)
在构造函数中-因此
i++
只重复一次,而
()
则无限重复

正确的称呼方式是:

    new REPEAT({
            i += 1; println(i)
    }) UNTIL (i == 100)
原因是您不必在scala中使用
Unit
type显式指定单个参数:

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

如果取消注释您的注释代码(
var i
定义了两次),它将不会编译。没有它-按预期打印1到100。如果您写入
重复{i+=1;println(i)}直到(i==100)
两次-它将导致堆栈溢出,因为它将从i=101开始,以i=无穷大结束。很抱歉,我没有清楚地表达它。在main方法中运行的代码是替换注释的代码。目前,我非常确定您的
UNTIL
方法不是尾部递归的,因为它既不是
private
也不是
final
。使用更长的循环,您也会得到一个
堆栈溢出。您应该向该方法添加
@tailrec
注释。如果取消注释您的注释代码(
var i
定义了两次),则不会编译该注释。没有它-按预期打印1到100。如果您写入
重复{i+=1;println(i)}直到(i==100)
两次-它将导致堆栈溢出,因为它将从i=101开始,以i=无穷大结束。很抱歉,我没有清楚地表达它。在main方法中运行的代码是替换注释的代码。目前,我非常确定您的
UNTIL
方法不是尾部递归的,因为它既不是
private
也不是
final
。使用更长的循环,您也会得到一个
堆栈溢出。您应该向该方法添加
@tailrec
注释。