从Akka Streams传递的隐式GraphBuilder对象在哪里

时间:2017-08-30 15:22:46

标签: scala akka-stream

我正在学习Akka Streams库并且有以下困惑。我看到一个Graphbuilder对象,它隐式传递给GraphDSL.create()(...)调用。 我无法理解实际的构建器对象在哪里可用?

 val g = RunnableGraph.fromGraph(GraphDSL.create() { implicit builder: GraphDSL.Builder[NotUsed] =>
  import GraphDSL.Implicits._
  val in = Source(1 to 10)
  val out = Sink.ignore

  val bcast = builder.add(Broadcast[Int](2))
  val merge = builder.add(Merge[Int](2))

  val f1, f2, f3, f4 = Flow[Int].map(_ + 10)

  in ~> f1 ~> bcast ~> f2 ~> merge ~> f3 ~> out
  bcast ~> f4 ~> merge
  ClosedShape
})

2 个答案:

答案 0 :(得分:1)

外部并非隐含地需要builder。如果你看一下create函数的签名

def create[S <: Shape]()(buildBlock: GraphDSL.Builder[NotUsed] ⇒ S): Graph[S, NotUsed]

您会注意到它只需要BuilderShape的功能。实际上,如果您从代码中删除implicit关键字,则仍应编译对create的调用。

但是,您需要稍后在代码中隐式使用该构建器,特别是在需要GraphDSL表示法~>时。如果您检查~>

的签名
def ~>[U >: T](to: Inlet[U])(implicit b: Builder[_]): Unit

您将看到这是需要隐式Builder的地方。这就是builder参数需要注释为implicit

的原因

答案 1 :(得分:0)

看一下这个来源让它更清晰。 调用者传入函数,而构建器的实例化是从create函数内部完成的。

来自akka/stream/scaladsl/GraphApply.scala.template

def create[S <: Shape]()(buildBlock: GraphDSL.Builder[NotUsed] ⇒ S): Graph[S, NotUsed] = {
    val builder = new GraphDSL.Builder
    val s = buildBlock(builder)
    val mod = builder.module.replaceShape(s)

    new GraphApply.GraphImpl(s, mod)
  }