ストリームは、クラスコンストラクターの引数として使用できます。
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は単純なインターフェイスです。
ほとんどの場合、コストのかかる操作を避けるために、ストリームをcolコンストラクター引数として使用したいと思います。デバッガーでは、HazelSimpleResultSetの初期化後も、colに表示される値がStream(xy、?)および "tlVal = null"のままであるため、場合によっては機能することがわかります。
さらに、テストのために、次のようにストリームを構成するブロックにprintlnを含めます。
keyvalues.foldLeft(Stream.empty[KeyType]){ case (a, b) => ({ println("evaluating "+ b); unpack[KeyType](b)}) #:: a}
ストリームが正確に評価されたときにコンソールでフォローするため。
したがって、動作する場合もありますが、HazelSimpleResultSetの初期化の最初の瞬間にストリームが完全に評価される場合もあります。渡されたストリームに関連する違いは見当たりません。その瞬間まで、評価されていないストリームであると確信しています。デバッガーで「ステップイン」すると、クラス本体に到達する前、つまりフィールドの初期化前に、クラス定義自体の行で評価されることがわかります。
編集:ストリームを参照しているフィールドがまったくないように(最適ではない)方法でクラスを定義できますが、それでもその動作は得られます。
CountMeインターフェースは、すべてのストリームを評価するcol.sizeを呼び出す「count」メソッドを定義します。怠惰なvalサイズでカウントを定義しようとしましたが、違いはありませんでした。
場合によっては機能しない理由が少しわかりません。Streamsの隠された警告について誰かが何かヒントを持っていますか?
編集:重要な注意:Streamオブジェクトは、評価する必要のある深刻な状態、つまりNoSQLデータベース(hazelcast)への参照をラップします。質問:ここでの注意点は何ですか?ストリームに評価に必要なステートフルリファレンスが含まれている場合、特に注意しなければならないことがありますか?