7

我目前正在通过“Scala 编程”一书学习 Scala。到目前为止,对于看起来很奇怪的所有事情都有很好的解释(从 Java 程序员的角度来看),但是这个使用 Stream 生成斐波那契数列的例子让我有点困惑:

def fibFrom(a: Int, b: Int): Stream[Int] =
  a #:: fibFrom(b, a + b)

Stream的构建是如何完成的?当然,#::运营商对此负有某种责任。我知道,因为它以 结尾:,所以它是右关联的,但这并不能解释 Stream 的创建。我猜它以某种方式隐式转换为构造函数,但我不明白为什么以及如何准确。

我已经在寻找答案Predef.scalaLowPriorityImplicits.scala但到目前为止还没有运气。

任何人都可以启发我吗?

4

2 回答 2

8

它是正确关联的,因此它可以作为正确参数的方法:

fibFrom(b, a + b).#::(a)

至少这是它试图在语法上做的事情。Stream[Int]没有这样的方法。幸运的是,对某些具有此方法(代码object Stream的类具有隐式含义。ConsWrapper

所以,在隐式解析之后你得到的是:

immutable.this.Stream.consWrapper(fibFrom(b, a + b)).#::(a)
于 2012-05-04T10:49:47.683 回答
2

流类似于列表。它只知道它的头部和流的其余部分:Stream(head: T, tail: Stream[T])。不同之处在于,一个 Stream 是懒惰地评估的。方法名称末尾的“:”表示该方法是右关联的。所以表达式 a #:: fibFrom(b, a + b) 被(由编译器)翻译成 fibFrom(b, a + b).#::(a)。

于 2012-05-04T10:54:30.220 回答