2017-04-08 47 views
0

下面的代碼無法編譯。覆蓋特徵中的隱式抽象成員 - 注入隱式依賴(類型實例) - 如何使其工作?

此代碼的目的是將隱式依賴注入到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 
} 

我看不出兩者有什麼代碼之間的差異,它們具有相同的結構。

爲什麼第二次編譯和第一次沒有?

我該如何進行第一次編譯?

我的目標是,我可以將implicits注入到UseImplicits的實現中。這樣我可以提供幾個實現(測試,生產)。

斯卡拉小提琴是在這裏:https://scalafiddle.io/sf/dm3OJSF/1

回答

2

導入UI implicits(由import UI._)轉換成電流範圍,正確調用UI.foo()之前,應該解決您的問題。


你可以注入所需UseImplicit(例如,進入Foo類),並把它作爲:

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

正確的,但我想繞過UI在Useimplicit'的'形式,如果我導入一個特定的實現,然後我不能注入作爲依賴的暗示,這將是整個故事的點 – jhegedus

+0

@jhegedus又增加了一個例子。 –

+0

謝謝,我需要看看我到家時是否可以完成這項工作,目標是將蛋糕模式與implicits結合起來,所以'UseImplicit'也會通過自我註釋注入 – jhegedus