在下面的代码示例中,有很多代码重复。有什么办法可以删除吗?我一直在思考这个问题,但仍然不知道。
abstract class RouteBase[E <: Entity](
)(
implicit
i: ClassTag[E],
en: Encoder[E],
de: Decoder[E],
sa: InterfaceToStateAccessor,
ec: ExecutionContext)
{
common concrete methods ...
abstract methods ...
}
abstract class GetRouteBase [E <: Entity] (
implicit
i: ClassTag[E],
en: Encoder[E],
de: Decoder[E],
sa: InterfaceToStateAccessor,
ec: ExecutionContext) extends RouteBase[E]
{
implemented methods used by Get operations ...
}
class GetRoute[E <: Entity](
)(
implicit
i: ClassTag[E],
en: Encoder[E],
de: Decoder[E],
sa: InterfaceToStateAccessor,
ec: ExecutionContext) extends GetRouteBase[E]
{
actual method implementations of all abstract methods ...
}
}
编辑:
有趣的是,这段代码编译得很好:
class A {
implicit val s:String = "bla"
}
class B extends A
{
def printImplicit(implicit s:String)={
println(s)
}
printImplicit
}
答案 0 :(得分:1)
您可以尝试创建聚合隐式上下文类并传递它。使用一些存根而不是实际类型,如
type Entity = Object
type MyEntity = String
trait Encoder[E] {}
trait Decoder[E] {}
trait InterfaceToStateAccessor {}
您可以创建以下内容:
@implicitNotFound("Make sure that you have implicit ClassTag, Encoder, Decoder, InterfaceToStateAccessor, and ExecutionContext visible here")
class RouteImplicitContext[E <: Entity](i: ClassTag[E],
en: Encoder[E],
de: Decoder[E],
sa: InterfaceToStateAccessor,
ec: ExecutionContext) {
implicit val ii: ClassTag[E] = i
implicit val ien: Encoder[E] = en
implicit val ide: Decoder[E] = de
implicit val isa: InterfaceToStateAccessor = sa
implicit val iec: ExecutionContext = ec
}
object RouteImplicitContext {
implicit def create[E <: Entity](implicit i: ClassTag[E],
en: Encoder[E],
de: Decoder[E],
sa: InterfaceToStateAccessor,
ec: ExecutionContext): RouteImplicitContext[E] = new RouteImplicitContext[E](i, en, de, sa, ec)
}
然后您可以将其用作
abstract class RouteBase[E <: Entity]()(implicit ctx: RouteImplicitContext[E]) {
def doSomethingStrange(e: Entity)(implicit i: ClassTag[E],
en: Encoder[E],
de: Decoder[E],
sa: InterfaceToStateAccessor,
ec: ExecutionContext): Unit = {
println(s"e = $e; implicits: i = $i, en=$en, de=$de, sa=$sa, ec=$ec")
}
}
abstract class GetRouteBase[E <: Entity](implicit ctx: RouteImplicitContext[E]) extends RouteBase[E] {
}
class GetRoute[E <: Entity]()(implicit ctx: RouteImplicitContext[E]) extends GetRouteBase[E] {
import ctx._ // <- this is important for code to compile
def callSomethingStrange(e: Entity) = {
doSomethingStrange(e)
}
}
def test(): Unit = {
implicit val en = new Encoder[MyEntity] {}
implicit val de = new Decoder[MyEntity] {}
implicit val sa = new InterfaceToStateAccessor {}
import scala.concurrent.ExecutionContext.Implicits.global
val gr = new GetRoute[MyEntity]()
gr.doSomethingStrange("abc")
}
此代码编译并运行正常。
答案 1 :(得分:0)
这是我能想到的最好的。我不确定在这个例子中是否可以减少代码重复。
trait T {
implicit val s:String
implicit val i:Int
}
trait A { T =>
def printA(implicit s:String) = {println("A"+s)}
}
trait B extends A
{ T=>
def printB(implicit i:Int) = {println("B"+i)}
}
trait C extends B
{ T=>
def printImplicit(implicit s:String,i:Int)={
println(s)
printA
printB
}
}
class D(implicit s2:String,i:Int) extends C {
printImplicit
}