Scala / Play:写入为流预设值的Enumeratee

时间:2012-06-11 09:04:19

标签: scala playframework playframework-2.0 enumerator iterate

我想编写一个枚举,只需将一个Input.El推入iteratee,然后返回剩余的iteratee。我把它称为prepend,因为它只是通过为它添加一个值来改变流。 这是我的尝试:

object Enumeratees {
  def prepend[T](toPrepend: T) = new Enumeratee[T, T] {
    def applyOn[A](inner: Iteratee[T, A]): Iteratee[T, Iteratee[T, A]] = {
      val prepended = Iteratee.flatten(inner.feed(Input.El(toPrepend)))
      Done(prepended, Input.Empty)
    }
  }
}

我现在通过

打电话
Enumerator(1,2,3,4) |>> (Enumeratees.prepend(0)  &>> Iteratee.foreach[Int]{i=>println(i)})

它只打印应该预先添加的0。枚举器中的其他值将被忽略。如果我也覆盖&>枚举的方法(变换方法),我可以使它工作:

def prepend[T](toPrepend: T) = new Enumeratee[T, T] {
  def applyOn[A](inner: Iteratee[T, A]): Iteratee[T, Iteratee[T, A]] = {
    val prepended = Iteratee.flatten(inner.feed(Input.El(toPrepend)))
    Done(prepended, Input.Empty)
  }

  override def transform[A](inner: Iteratee[T,A]): Iteratee[T,A] =
    Iteratee.flatten(inner.feed(Input.El(toPrepend)))
}

但这不是一种非常干净的方式,因为applyOn方法仍然无效。 我想我错误地认识了applyOn方法的含义。在我看来,它应该返回一个返回原始iteratee的iteratee,然后在原始的iteratee上继续输入。

上面的转换方法应该解释一下,我想从我的枚举中得到什么样的行为。如何通过覆盖applyOn而不是transform?

来实现此行为

2 个答案:

答案 0 :(得分:7)

您可以编辑前缀Enumeratee,如下所示:

object Enumeratees {
  def prepend[T](toPrepend: T) = new Enumeratee[T, T] {
    def applyOn[A](inner: Iteratee[T, A]): Iteratee[T, Iteratee[T, A]] = {
      val prepended = Iteratee.flatten(inner.feed(Input.El(toPrepend)))
      Enumeratee.passAlong[T](prepended)
    }
  }
}

或者在将Enumeratee和Enumerator应用到它之后,你得到了原始的Iteratee,类似于Scala: Getting original iteratee after applying enumeratee (example from play documentation doesn't compile)

当外部完成时,

&>>将结束内部迭代。这是能够获得Iteratee[EOuter,AInner]的唯一方法,因为Enumeratee主要是关于适应。

答案 1 :(得分:0)

怎么样?
Enumerator(1,2,3,4) |>>
Iteratee.flatten( Enumerator(0) |>> Iteratee.foreach[Int]{i=>println(i)} )

Enumerator(1,2,3,4) |>> (Enumeratees.prepend2(0) &> Iteratee.foreach[Int]{i=>println(i)})