2

ストリームは、クラスコンストラクターの引数として使用できます。

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)への参照をラップします。質問:ここでの注意点は何ですか?ストリームに評価に必要なステートフルリファレンスが含まれている場合、特に注意しなければならないことがありますか?

4

1 に答える 1

1

このように作成する場合Stream

Stream ({println("eval 1"); 1}, {println("eval 2"); 2})

Stream.apply次に、実際に次のように実装されているものを呼び出しています。

/** A stream consisting of given elements */
override def apply[A](xs: A*): Stream[A] = xs.toStream

つまり、実際に起こることは次のとおりです。

  1. すべての要素が評価されます!
  2. これらのSeq要素を含む が作成されます。
  3. そこからAStreamが生まれるSeq

ご覧のStreamとおり、この方法で作成すると、そのすべての要素が積極的に評価されます。これは、遅延評価されたを作成する方法ではありませんStream。あなたがやりたいことは、オペランドを遅延して評価する#::and#:::演算子をおそらく使用することです。使用法についてはドキュメントを参照してください。

于 2013-03-11T13:42:04.980 に答える