【问题标题】:overriding implicit abstract members in a trait - injection of implicit dependencies (type class instances) - how to make it work?覆盖特征中的隐式抽象成员 - 注入隐式依赖项(类型类实例) - 如何使其工作?
【发布时间】:2017-04-08 11:04:10
【问题描述】:

下面的代码编译失败。

这段代码的目的是将隐式依赖注入UseImplicit。 换句话说,它是类型类实例的依赖注入。

trait StuffProvider[T]{
  implicit val provideStuff:() => T
}

trait UseImplicit{
  implicit val gimmiString: StuffProvider[String] // implicit dependency
  implicit val gimmiInt: StuffProvider[Int]
  def foo[T:StuffProvider]() :T = implicitly[StuffProvider[T]].provideStuff()
}

object Main{

  object StringProvider extends StuffProvider[String]{
    implicit val provideStuff: () => String= () => "bla"
  }

  object IntProvider extends StuffProvider[Int]{
    implicit val  provideStuff: () => Int= () => 42
  }

  object UI extends UseImplicit {
    implicit val gimmiString=StringProvider // injection
    implicit val gimmiInt=IntProvider
  }

  val f:Int=UI.foo[Int]() //  Error:(27, 15) could not find implicit value for evidence parameter of type StuffProvider[T]

}

但这编译得很好:

trait UseImplicit2{
  implicit val gimmiString: String
  def foo() :String = implicitly[String]
}

object Main2{

  object UI extends UseImplicit2 {
    override implicit val gimmiString:String = "s"
  }
  val f=UI.foo() // this compiles just fine
}

我看不出这两个代码有什么区别,它们的结构相同。

为什么第二个编译而第一个不编译?

如何进行第一次编译?

目标是我可以将隐式注入到UseImplicits 的实现中。这样我就可以提供几种实现方式(测试、生产)。

Scala Fiddle 在这里:https://scalafiddle.io/sf/dm3OJSF/1

【问题讨论】:

    标签: scala traits implicit


    【解决方案1】:

    在调用UI.foo() 之前,将UI 隐含(由import UI._)导入当前范围,应该可以解决您的问题。


    您可以注入所需的UseImplicit(例如注入Foo 类)并将其用作:

    case class Foo(ui: UseImplicit) {
      import ui._
      val f: Int = ui.foo[Int]() //Use your injected `UseImplicit`
    }
    

    【讨论】:

    • 对,但我想以Useimplicit 的形式传递 UI,如果我导入特定的实现,那么我不能将隐含作为依赖注入,这将是整个故事的重点
    • @jhegedus 添加了另一个示例。
    • 谢谢,我需要看看我回家后能不能完成这项工作,目标是将蛋糕图案与隐式结合起来,所以UseImplicit也将通过自我类型注释注入
    • 我试过了,好像不行:scalafiddle.io/sf/dm3OJSF/1
    • 设法让它工作,感谢您的启发! gist.github.com/jhegedus42/3aa01b78e271c7bd4851abf73c7f718d
    猜你喜欢
    • 2016-05-28
    • 1970-01-01
    • 2012-12-29
    • 2015-02-14
    • 2015-10-02
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    • 2010-12-01
    相关资源
    最近更新 更多