![](/img/trans.png)
[英]Akka Streams: No-arg GraphDSL.create() vs GraphDSL.create(sink)
[英]Akka Streams: Why does the GraphDSL.Builder have to be marked as implicit?
我努力將Scala中的implicit
概念應用於Akka Streams。
根據http://docs.scala-lang.org/overviews/core/implicit-classes.html,Scala中implicit
類的基本概念是,對於5 times prinln("foo")
,將創建一個IntWithTimes
對象,可以通過導入Helpers._
隱式獲得方法times
。
object Helpers {
implicit class IntWithTimes(x: Int) {
def times[A](f: => A): Unit = {
def loop(current: Int): Unit =
if(current > 0) {
f
loop(current - 1)
}
loop(x)
}
}
}
讓我們考慮以下示例:
val g = RunnableGraph.fromGraph(GraphDSL.create() {
implicit builder: GraphDSL.Builder[Unit] =>
import GraphDSL.Implicits._
val in = Source(1 to 100)
val flow = Flow[Int].map(_ + 1)
val out = Sink.foreach(println)
in ~> flow ~> out
ClosedShape
})
g.run()
顯然對於Scala和Akka來說是新手,到目前為止,我不滿意的理論是使用GraphDSL
create()
可以通過將Builder
傳遞到其中GraphDSL
創建RunnableGraph
。
為什么必須將其標記為implicit
? 如果不進行設置,即使已顯式導入GraphDSL.Implicits._
也無法解析~>
運算符。
implicit
在Scala中有多個用例,其中之一就是您提到的隱式類。 但是,還有隱式參數和隱式轉換 。 我建議您仔細閱讀這些內容,因為此答案的范圍太廣了,並且會不必要地重復信息。 但是請注意, 對於具有隱式轉換的類 ,隱式類主要是語法糖 ,因此它們的功能相同。
如果不進行設置,即使已顯式導入GraphDSL.Implicits._,也無法解析〜>運算符。
這FlowOps
隱式轉換導入到實際定義~>
FlowOps
中。 至此,Scala知道了轉換。 但是,要實際執行此操作,需要一個隱式參數 b : Builder[_]
。 看一下Implicits
中的轉換定義:
implicit def fanOut2flow[I, O](j: UniformFanOutShape[I, O])(implicit b: Builder[_]): PortOps[O]
現在,您可以將任何Builder[_]
標記為隱式,如果缺少此參數,Scala會自動為您填充此參數。 從您的Builder中刪除implicit
關鍵字意味着不再有任何隱式值可用於填充此參數,這意味着無法進行轉換,隨后~>
方法不可用。
但是,您可以手動調用隱式轉換並自己填寫缺失的參數(繞過整個隱式參數的功能),但是相比之下,這看起來非常丑陋/冗長:
in ~> // .. and so on
// would become
fanOut2flow(in)(builder) ~> // .. and so on
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.