我很难将Scala中implicit
的想法应用到Akka Streams。
根据http://docs.scala-lang.org/overviews/core/implicit-classes.html,Scala中implicit
类的基本概念是5 times prinln("foo")
创建IntWithTimes
的对象,使方法{{1} }通过导入times
隐式提供。
Helpers._
让我们考虑以下示例:
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)
}
}
}
显然是Scala和Akka的新手,到目前为止我不满意的理论是,使用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()
create()
通过将GraphDSL
传递给RunnableGraph
来创建Builder
。
为什么必须将其标记为implicit
?如果离开,~>
运算符将无法再解析 - 即使GraphDSL.Implicits._
已明确导入。
答案 0 :(得分:3)
implicit
在Scala中有多个用例,其中一个是你提到的隐式类。但是,还有implicit parameters和implicit conversions。我建议阅读这些,这个答案的范围有点多,并且会不必要地复制信息。但请注意,隐式类主要是syntactic sugar for a class with an implicit conversion,因此它们的功能相同。
如果离开,那么〜>无法解析运算符 - 即使显式导入了GraphDSL.Implicits._。
这会将隐含的转化导入FlowOps
,其中~>
实际定义。此时Scala知道转换。但是,要实际执行此操作,需要隐式参数 b : Builder[_]
。请查看Implicits
中的转化定义:
implicit def fanOut2flow[I, O](j: UniformFanOutShape[I, O])(implicit b: Builder[_]): PortOps[O]
现在您可以将任何Builder[_]
标记为隐式,如果丢失,Scala会自动为您填写此参数。从Builder中删除implicit
关键字意味着不再有任何隐含值可用于填充此参数,这意味着无法进行转换,随后方法~>
无效。< / p>
然而,您可以自由地手动调用隐式转换并自行填写缺少的参数(绕过整个隐式参数功能),但相比之下,这看起来非常丑陋/冗长:
in ~> // .. and so on
// would become
fanOut2flow(in)(builder) ~> // .. and so on