2017-04-08 16 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 
} 

私は2つのコードの違いは何であるか表示されていない、彼らは同じ構造を有しています。

なぜ2番目のコンパイルは最初のコンパイルではないのですか?

最初のコンパイルはどのようにすればできますか?

目標はUseImplicitsの実現にインプリシットを注入できることです。私はいくつかの実現(テスト、生産)を提供することができます。

Scalaのフィドルはここにある:https://scalafiddle.io/sf/dm3OJSF/1

答えて

2

が現在のスコープにUI暗黙(import UI._による)をインポート、右UI.foo()を呼び出す前に、あなたの問題を解決する必要があります。


あなたは(例えばFooクラスに)希望UseImplicitを注入し、としてそれを使用することができます。

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

右が、私は、私ならば、Useimplicit' 'の形でUI周りを通過したいです特定のインプリメンテーションをインポートしてから、依存関係としてインプリシットを注入することはできません。それは全体の話のポイントになります。 – jhegedus

+0

@jhegedusに別の例が追加されました。 –

+0

ありがとう、私は家に帰るときにこの仕事をすることができるかどうかを知る必要があります。目的はケーキパターンを暗黙のものと組み合わせることです。したがって、UseImplicitも自己タイプの注釈で注入されます – jhegedus

関連する問題