我目前正在通过“Scala编程”一书来学习Scala。到目前为止,对于看起来很奇怪的所有内容(从Java程序员的角度来看)都有很好的解释,但是这个使用Stream生成Fibonacci序列的例子让我感到很困惑:
def fibFrom(a: Int, b: Int): Stream[Int] =
a #:: fibFrom(b, a + b)
如何完成Stream的构建?当然,#::
运算符对此负有某种责任。我理解,因为它以:
结束,所以它是右关联的,但这并不能解释Stream的创建。我猜它是以某种方式隐式转换为构造函数,但我不明白为什么以及如何确切。
我已经在Predef.scala
和LowPriorityImplicits.scala
寻找了答案,但到目前为止还没有运气。
任何人都可以启发我吗?
答案 0 :(得分:8)
它是正确的关联,所以它作为右边参数的方法:
fibFrom(b, a + b).#::(a)
至少这是它试图在语法上做的事情。 Stream[Int]
没有这样的方法。幸运的是,object Stream
隐含了某个类ConsWrapper
,它有这个方法(code)。
所以,你在隐式解决之后得到的是:
immutable.this.Stream.consWrapper(fibFrom(b, a + b)).#::(a)
答案 1 :(得分:2)
Stream类似于List。它只知道它的头部和流的其余部分:Stream(head:T,tail:Stream [T])。不同的是,流被懒惰地评估。方法名称末尾的“:”表示该方法是右关联的。所以表达式#:: fibFrom(b,a + b)被(由编译器)翻译成fibFrom(b,a + b)。#::( a)。