为什么抛出堆栈溢出异常?

时间:2011-06-09 19:15:19

标签: scala

......尽管它可以进行尾调用优化吗?

def areStreamsEqual(stream1: InputStream, stream2: InputStream): Boolean =
{
    val one = stream1.read()
    val two = stream2.read()
    if(one != two)
        false
    else if(one == -1 && two == -1)
        true
    else
        areStreamsEqual(stream1, stream2)
}

有没有强制Scala编译器在这里进行尾调用优化?

2 个答案:

答案 0 :(得分:6)

感谢pst关于@tailrec的评论。鉴于注释scala编译器错误消息解释了不优化方法的原因。

<filename>.scala:64: error: could not optimize @tailrec annotated method: it is neither private nor final so can be overridden
def areStreamsEqual(stream1: InputStream, stream2: InputStream): Boolean =

使方法私有对其进行排序

我怀疑在字节码级别上,有两条调用方法的指令:virtual_call和tail_call。

答案 1 :(得分:1)

对于任何试图在REPL中重新创建编译器错误的人,你必须将方法包装在这样的类中:

class Test {
@annotation.tailrec def areStreamsEqual(stream1: InputStream, stream2: InputStream): Boolean =
{
    val one = stream1.read()
    val two = stream2.read()
    if(one != two)
        false
    else if(one == -1 && two == -1)
        true
    else
        areStreamsEqual(stream1, stream2)
}
}

如果你只是将方法插入到REPL中,那么TCO就好了,因为类外的方法不能被覆盖。