我如何定义隐含的类,可以隐式地同时继承基类和派生类

时间:2018-10-19 14:21:10

标签: scala akka implicit-conversion implicit akka-stream

我如何定义可以同时继承基类和派生类的隐式类?

我想实现既可以Flow又可以Source使用的类。我尝试过了

{
"userid" => 127,
"@version" => "1",
"@timestamp" => 2018-10-18T13:54:37.641Z,
"type" => "SELL"
}

但是在implicit class FlowOpsMatExt[T, Mat](val flow: FlowOpsMat[T, Mat]) { def groupSortedByKey[K](keyForItem: T ⇒ K, maxBufferSize: Int): flow.Repr[Vector[T]] } 实例上调用时,我得到了Source[],我不能再将其用作源。所以我试图欺骗它

FlowOpsMat

,但是由于某种原因它无法检测类型。在显式通话中

implicit class FlowOpsMatExt[T, Mat, C <: FlowOpsMat[T, Mat]](val flow2: C)

我收到以下错误消息

new FlowOpsMatExt(source_instance)

再现的最小示例:https://gist.github.com/931a313546f14e809b705e86743dcdb0

如果我明确指定所有类型Error:(106, 5) inferred type arguments [Nothing,Nothing,akka.stream.scaladsl.Source[akka.util.ByteString,akka.NotUsed]] do not conform to class FlowOpsMatExt's type parameter bounds [T,Mat,C <: akka.stream.scaladsl.FlowOpsMat[T,Mat]] new FlowOpsMatExt(src) ,它将进行编译,但会扼杀使用隐式类的好处。

我想念什么?

我能想到的最好的办法是将扩展函数的实现保留在抽象类中,并从中实现两个隐式类

new FlowOpsMatExt[ByteString, NotUsed, Source[ByteString, NotUsed]](src)

1 个答案:

答案 0 :(得分:2)

来自documentation

  

高级Scala用户可能想知道是否有可能编写扩展FlowOps的扩展方法以允许更好的语法。简短的答案是,Scala 2不以完全通用的方式支持此功能,问题在于,由于SourceFlow和{{ 1}}的类型参数数量和种类有所不同。尽管有可能编写一个隐式类来对它们进行一般性的扩充,但由于SI-2712,此类将需要使用所有类型参数的显式实例化。有关统一对Source和Flow的扩展的部分解决方法,请参见this sketch by R. Kuhn

     

...

     

有趣的是,此问题的简化形式已进入dotty test suite。 Dotty是Scala到Scala 3的开发版本。