我正在学习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
})
答案 0 :(得分:1)
外部并非隐含地需要builder
。如果你看一下create
函数的签名
def create[S <: Shape]()(buildBlock: GraphDSL.Builder[NotUsed] ⇒ S): Graph[S, NotUsed]
您会注意到它只需要Builder
到Shape
的功能。实际上,如果您从代码中删除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)
}