Scala括号java.lang.StackOverflower错误
我在处理这个愚蠢的递归代码时遇到了麻烦。它在不应该的地方抛出StackOverflowerError错误,或者我认为是这样。我查看了字节码,发现了问题 有人能给我解释一下Scala在引擎盖下干什么吗 JVM和Scala版本:Scala括号java.lang.StackOverflower错误,scala,stack-overflow,Scala,Stack Overflow,我在处理这个愚蠢的递归代码时遇到了麻烦。它在不应该的地方抛出StackOverflowerError错误,或者我认为是这样。我查看了字节码,发现了问题 有人能给我解释一下Scala在引擎盖下干什么吗 JVM和Scala版本: $ java -version java version "1.6.0_45" Java(TM) SE Runtime Environment (build 1.6.0_45-b06-451-11M4406) Java HotSpot(TM) 64-Bit Server V
$ java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06-451-11M4406)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01-451, mixed mode)
$ scala -version
Scala code runner version 2.10.3 -- Copyright 2002-2013, LAMP/EPFL
以下是小程序:
package objsets
class Recur(layer: Int, value: Int) {
def inner = new Recur(layer - 1, value + 1)
def getVal: Int = {
if (layer <= 0) value
else // if surrond these 2 expressions with brackets, error will go away
//{
print("");
inner.getVal
//}
}
}
object Recur {
def main(args: Array[String]) = {
println((new Recur(0, 5)).getVal) // throw java.lang.StackOverflowError
}
}
括号内:
public int getVal();
Code:
0: aload_0
1: getfield #25; //Field layer:I
4: iconst_0
5: if_icmpgt 18
8: aload_0
9: getfield #27; //Field value:I
12: invokestatic #41; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
15: goto 29 // not sure why it goes to 29
18: getstatic #46; //Field scala/Predef$.MODULE$:Lscala/Predef$;
21: ldc #48; //String
23: invokevirtual #52; //Method scala/Predef$.print:(Ljava/lang/Object;)V
26: getstatic #58; //Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
29: pop
30: aload_0
31: invokevirtual #60; //Method inner:()Lobjsets/Recur;
34: invokevirtual #62; //Method getVal:()I
37: ireturn
public int getVal();
Code:
0: aload_0
1: getfield #25; //Field layer:I
4: iconst_0
5: if_icmpgt 15
8: aload_0
9: getfield #27; //Field value:I
12: goto 30
15: getstatic #40; //Field scala/Predef$.MODULE$:Lscala/Predef$;
18: ldc #42; //String
20: invokevirtual #46; //Method scala/Predef$.print:(Ljava/lang/Object;)V
23: aload_0
24: invokevirtual #48; //Method inner:()Lobjsets/Recur;
27: invokevirtual #50; //Method getVal:()I
30: ireturn
问题似乎在于无括号版本中的“goto 29”
有人能给我解释一下Scala在引擎盖下干什么吗?这是因为Scala试图找出(print(“”;internal.getVal)的值类型,但在编译时无法做到这一点吗?如果else块包含多个语句,则需要用括号括住这些语句,否则,print语句是else块中唯一的语句,并且您的
getVal
方法将始终返回internal.getVal
不带括号,您的代码相当于:
class Recur(layer: Int, value: Int) {
def inner = new Recur(layer - 1, value + 1)
def getVal: Int = {
if (layer <= 0) value else print("")
return inner.getVal // added explicit return
}
}
当<代码>图层
class Recur(layer: Int, value: Int) {
def inner = new Recur(layer - 1, value + 1)
def getVal: Int = {
return (if (layer <= 0) value
else {
print("");
inner.getVal
}
)
}
}