2017-04-08 2 views
0

Der folgende Code kann nicht kompiliert werden.überschreiben implizite abstrakte Mitglieder in einem Merkmal - Injektion von impliziten Abhängigkeiten (Typ Klasseninstanzen) - wie es funktioniert?

Der Zweck dieses Codes besteht darin, die impliziten Abhängigkeiten in UseImplicit zu injizieren. Mit anderen Worten, es ist eine Abhängigkeitsinjektion für Klasseninstanzen.

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] 

} 

aber dies stellt nur gut:

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 
} 

Ich sehe nicht, was der Unterschied zwischen den beiden Codes ist, sie haben die gleiche Struktur.

Warum kompiliert die zweite und die erste nicht?

Wie kann ich die erste kompilieren?

Das Ziel ist, dass ich die Implikate in eine Realisierung von UseImplicits injizieren kann. Damit kann ich mehrere Realisierungen bereitstellen (Testen, Produzieren).

Scala Fiddle ist hier: https://scalafiddle.io/sf/dm3OJSF/1

Antwort

2

importieren UI implicits (von import UI._) in aktuellen Bereich, direkt vor UI.foo() Aufruf, sollte Ihr Problem beheben.


Sie können die UseImplicit (zB in eine Foo Klasse) gewünscht injizieren und verwenden Sie es als:

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

Recht, aber ich will laufen um UI in Form von 'Useimplicit', ich, wenn Importieren Sie eine spezifische Implementierung dann kann ich nicht die Implicits als Abhängigkeit injizieren, das wäre der Punkt der ganzen Geschichte – jhegedus

+0

@jhegedus ein weiteres Beispiel hinzugefügt. –

+0

danke, ich muss sehen, ob ich das schaffen kann, wenn ich nach Hause komme, das Ziel ist, das Kuchenmuster mit implicits zu kombinieren, also würde "UseImplicit" auch über eine Selbsttyp-Annotation injiziert werden – jhegedus

Verwandte Themen