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

lun*_*ain 4 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)
}
Run Code Online (Sandbox Code Playgroud)

反正是否强制Scala编译器在这里进行尾调用优化?

lun*_*ain 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 =
Run Code Online (Sandbox Code Playgroud)

使方法私有排序

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

  • 关于你的最后一条评论,不,字节码级别不支持尾调用.scalac实际上将您的递归方法重写为迭代方法. (3认同)
  • 在字节码级别有四个调用指令:`invokestatic`,`invokespecial`,`invokevirtual`,`invokeinterface`.第五个,`invokedynamic`,将在Java 7中出现.Scala不会将这些都用于尾递归方法.相反,它将调用转换为一个简单的`goto`,它跳转到方法的顶部.如果您将方法编写为`while`循环而不是递归函数,则这与生成的字节码完全相同. (3认同)