【问题标题】:Scala recursive closure compile errorScala递归闭包编译错误
【发布时间】:2011-05-03 06:20:45
【问题描述】:

我正在尝试实现一个记忆斐波那契数函数,但我遇到了无法解决的编译错误。以下代码是我目前所拥有的。

var fibs = Map.empty[Int, Int]
fibs += 0 -> 1
fibs += 1 -> 1
fibs += 2 -> 2
val fib = (n: Int) => {
  if (fibs.contains(n)) return fibs.apply(n)
  else{
    // Error here
    val result = fib(n - 1) + fib(n - 2)
    fibs+= n -> result
    return result
  }
}
println(fib(100))

错误是:

递归fib需要类型

我已经尝试在不同的地方输入闭包的返回类型,但我似乎无法让它工作。

val fib = (n: Int): Int => { 这样声明闭包会产生不同的编译错误。

你能帮我解决这个编译错误吗?

【问题讨论】:

    标签: scala recursion closures


    【解决方案1】:

    您可以按照 Ben Jackson 的建议定义一个方法(即def fib (n: Int): Int = ...)。

    函数值不能递归。 编辑:原来是they can be recursive;您只需要更多地帮助类型推断器。另外,你需要摆脱return;只能在方法中使用。

    以下作品:

    var fibs = Map.empty[Int, Int]
    fibs += 0 -> 1
    fibs += 1 -> 1
    fibs += 2 -> 2
    val fib: (Int => Int) = n => {
      if(fibs contains n) 
        fibs(n)
      else {
        val result = fib(n - 1) + fib(n - 2)
        fibs += n -> result
        result
      }
    }
    println(fib(100))
    

    您还应该查看this blogpost,以了解如何借助 lambda 抽象出记忆化逻辑。

    【解决方案2】:

    去掉return,因为它们只能与def一起使用,而不是val,并声明fib的类型,因为这是递归定义的Scala要求。

    val fib: (Int => Int) = (n: Int) => {
      if (fibs.contains(n)) fibs.apply(n)
      else{
        val result = fib(n - 1) + fib(n - 2)
        fibs+= n -> result
        result
      }
    }
    

    注意fib(100) 会溢出Int

    【讨论】:

      【解决方案3】:

      您必须明确设置递归函数的返回类型。它无法推断类型,因为推断将是循环的。所以:def fib (n: Int): Int = ...

      【讨论】:

      • val fib = (n: Int): Int => { 这样声明闭包会产生不同的编译错误。
      • 我给了你def 语法。如果你想使用val 来定义函数,你必须像往常一样给它一个类型:val fib: (Int => Int) = (n: Int) => { ... }
      猜你喜欢
      • 1970-01-01
      • 2014-04-28
      • 1970-01-01
      • 2015-01-17
      • 1970-01-01
      • 1970-01-01
      • 2015-05-30
      • 1970-01-01
      • 2011-11-12
      相关资源
      最近更新 更多