我是Scala的新手,我正在使用Array.tabulate方法。我在执行这段简化的代码片段时遇到了StackOverFlowError(最初是一个dp问题)。
import Lazy._
class Lazy[A](x: => A) {
lazy val value = x
}
object Lazy {
def apply[A](x: => A) = new Lazy(x)
implicit def fromLazy[A](z: Lazy[A]): A = z.value
implicit def toLazy[A](x: => A): Lazy[A] = Lazy(x)
}
def tabulatePlay(): Int = {
lazy val arr: Array[Array[Lazy[Int]]] = Array.tabulate(10, 10) { (i, j) =>
if (i == 0 && j == 0)
0 // some number
else
arr(0)(0)
}
arr(0)(0)
}
调试,我注意到,因为arr是惰性的,当它到达arr(0)(0)表达式时,它会尝试通过再次调用Array.tabulate方法来评估它 - 无限地反复遍历。
我做错了什么? (我更新了代码片段,因为我基于Dynamic programming in the functional paradigm中给出的解决方案,特别是Antal S-Z的答案)
答案 0 :(得分:0)
您已经有效地导致了无限递归。您根本无法在其自己的初始化代码中引用lazy val
。您需要单独计算arr(0)(0)
。
答案 1 :(得分:0)
我不确定为什么你在构建之前尝试访问arr,tabulate似乎用于用函数填充数组 - 调用arr总是会导致无限递归。
请参阅Rex在这里的例子(以及对他的投票),也许这会有所帮助。
In a multidimensional sequence created with tabulate, is the innermost seq the 1. dimension?
答案 2 :(得分:0)
我能够通过在Lazy中包装arr(0)(0)来解决这个问题,因此它被评估为call-by-name参数,因此不会在tabulate方法中评估arr。我引用的代码是使用implicits(二进制+运算符)自动转换它,所以它不是很明确。
def tabulatePlay(): Int = {
lazy val arr: Array[Array[Lazy[Int]]] = Array.tabulate(10, 10) { (i, j) =>
if (i == 0 && j == 0)
1 // some number
else
new Lazy(arr(0)(0))
}
arr(0)(0)
}
谢谢大家。