流可以用作类构造函数参数:
scala> ( 0 to 10).toStream.map(i =>{println("bla" + i); -i})
bla0
res0: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> class B(val a:Seq[Int]){println(a.tail.head)}
defined class B
scala> new B(res0)
bla1
-1
res1: B = B@fdb84e
因此,尽管作为 Seq 参数提交,并且虽然被部分评估,但 Stream 并未得到完全评估。按预期工作。
我有这样的课:
class HazelSimpleResultSet[T] (col: Seq[T], comparator:Comparator[T]) extends HGRandomAccessResult[T] with CountMe
{
val foo: Int = -1 // col of type Stream[T] already fully evaluated here.
def count = col.size
....
}
其中 HGRandomAccessResult 和 CountMe 是简单的接口。
大多数情况下,我想使用 Streams 作为 col 构造函数参数,以避免昂贵的操作。在调试器中,我可以看出它在某些情况下有效,因为 col 显示的值仍然是 Stream(xy, ?) 和“tlVal = null”,即使在 HazelSimpleResultSet 初始化之后也是如此。
此外,为了测试,我在构建 Streams 的块中包含 println,如下所示:
keyvalues.foldLeft(Stream.empty[KeyType]){ case (a, b) => ({ println("evaluating "+ b); unpack[KeyType](b)}) #:: a}
以便在准确评估 Stream 时在控制台中跟踪。
因此,在某些情况下它可以工作,但在某些情况下,Stream 在 HazelSimpleResultSet 初始化的最初时刻得到全面评估。我看不出提交的 Stream 没有相关差异,我只是确定他们在那一刻之前是未经评估的 Streams。使用调试器“进入”,我可以看到它在类定义本身的行中被评估,甚至在到达类主体之前,即在任何字段的初始化之前。
编辑:我可以以(次优)方式定义类,使得根本没有字段引用流,但我仍然得到这种行为。
CountMe 接口定义了一个“count”方法,该方法调用 col.size,然后评估所有 Stream。我试图根据惰性 val 大小来定义计数,但这并没有什么不同。
我有点不知所措,为什么它在某些情况下不起作用。有人对 Streams 的隐藏警告有任何提示吗?
编辑:重要说明:Stream 对象包含了一些需要评估的严重状态,即对 NoSQL 数据库(hazelcast)的引用。问题:这里有什么注意事项?当我的 Stream 携带评估所需的有状态引用时,有什么特别需要注意的吗?