覆盖特征中的隐式抽象成员 - 隐式依赖注入(类型 class 实例) - 如何使其工作?
overriding implicit abstract members in a trait - injection of implicit dependencies (type class instances) - how to make it work?
下面的代码编译失败。
此代码的目的是将隐式依赖项注入 UseImplicit
。
换句话说,它是类型 class 实例的依赖注入。
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
在调用 UI.foo()
之前将 UI
隐含(通过 import UI._
)导入当前范围应该可以解决您的问题。
您可以注入所需的 UseImplicit
(例如注入 Foo
class)并将其用作:
case class Foo(ui: UseImplicit) {
import ui._
val f: Int = ui.foo[Int]() //Use your injected `UseImplicit`
}
下面的代码编译失败。
此代码的目的是将隐式依赖项注入 UseImplicit
。
换句话说,它是类型 class 实例的依赖注入。
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
在调用 UI.foo()
之前将 UI
隐含(通过 import UI._
)导入当前范围应该可以解决您的问题。
您可以注入所需的 UseImplicit
(例如注入 Foo
class)并将其用作:
case class Foo(ui: UseImplicit) {
import ui._
val f: Int = ui.foo[Int]() //Use your injected `UseImplicit`
}