我一直在研究一些关于 scala 无限流的帖子,以更好地包装我的内容 围绕这个概念。我喜欢 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)
}
所以这个解决方案似乎确实基于覆盖。所以,现在我想知道..到底是什么 Scala 构造有某种类型“T”的 def,其中该值的值正在发生 block 包含另一个 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
,您必须首先创建一个类,扩展
已包含方法 X
的其他类。在您的示例中,您实际上并没有在任何地方创建新类!在这里,您刚刚在另一个函数中创建了一个嵌套函数,不幸的是,该函数被称为 tail
(因此与 Stream
中的函数之一具有相同的名称)。
所以基本上,fib
方法返回一个 Stream
实例,该实例是由嵌套的 tail
函数递归创建的。要创建 Stream
的实际实例,该方法使用 #::
运算符。您没有创建一个新类,而只是创建一个新实例。
doc很好地解释了 #::
正在做什么。
尝试将名称从 tail
更改为 myTail
(或不属于 Stream
的任何其他名称),您就会看到它仍然有效。
至于为什么要使用此构造:一个常见的原因是构建代码,您会注意到不能在外部方法之外使用该 tail
函数。
关于scala - 困惑重新 : solution to fibonnaci numbers with Scala infinite streams that used a def'd method within a def,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31778327/