混淆回复:使用 def 中使用 def'd 方法的 Scala 无限流解决斐波那契数

confusion re: solution to fibonnaci numbers with Scala infinite streams that used a def'd method within a def

我一直在研究一些关于 scala infinite streams 的帖子,以更好地总结我的 围绕这个概念。我喜欢 this post 中的简单解决方案, 我在下面转载了:

def fib: Stream[Long] = {
  def tail(h: Long, n: Long): Stream[Long] = h #:: tail(n, h + n)
  tail(0, 1)
}

我对正在发生的事情的初步理解是我们正在返回一个 Stream[Long] 对象 重写了 tail 方法。为了验证那个(看似不正确的)假设,我做了 以下,将无法编译:

def fib: Stream[Long] = {

  override def tail(h: Long, n: Long): Stream[Long] = h #:: tail(n, h + n)
     ^
     |
   ~error~~~

  tail(0, 1)
}

所以这个解决方案似乎确实基于覆盖。所以,现在我想知道..到底是什么 正在使用具有某种类型 'T' 的 def 的 Scala 结构,其中的值 块包含另一个 def,乍一看似乎覆盖了 T ?

的方法

在此先感谢您的启发!

编辑 - 这是在优秀答案中尝试解决方案的结果 马特乌斯·迪姆奇克 :

object Foolaround  extends App {

  def fib: Stream[Long] = {
    def pail(h: Long, n: Long): Stream[Long] = h #:: pail(n, h + n)
    pail(0, 1)
  }

  var x = fib.tail.tail.tail.tail.tail.head
  println (s"results: ${x}")
}

要覆盖方法 X,您必须首先创建一个 class,extends 其他 class 已经包含方法 X。在您的示例中,您实际上并没有在任何地方创建新的 class !在这里,您刚刚在另一个函数中创建了一个嵌套函数,不幸的是,该函数称为 tail(因此与 Stream 中的一个函数同名)。

所以基本上 fib 方法返回一个 Stream 实例,它是由嵌套的 tail 函数递归创建的。要创建 Stream 的实际实例,该方法正在使用 #:: 运算符。您不是在创建新的 class,只是一个新实例。

doc 很好地解释了 #:: 在做什么。

尝试将名称从 tail 更改为 myTail(或不属于 os 和 Stream 的任何其他名称),您会发现它仍然有效。

至于你为什么要使用这个结构:一个常见的原因是为了构建你的代码,你会注意到你不能在它的外部方法之外使用那个 tail 函数。