2012-04-15 10 views
3

diesen Fall Klasse vor:Mit expliziten Wert zu impliziten Parameter als neue implizite Wert übergeben

case class IntPrinter(implicit val i: Int) { 
    def print()(implicit i: Int) = println(i) 
} 

ich Instanz kann es explizit einen Wert für das implizite Argument wie folgt übergeben:

val p = IntPrinter()(9) 

I‘ Im IRC wurde mir gesagt, dass der explizit übergebene Wert von jetzt an implizit an den Drucker übergeben wird, wenn er aufgerufen wird, aber das ist nicht der Fall:

p.print() 
error: could not find implicit value for parameter i: Int 

Mache ich etwas falsch oder habe ich falsche Informationen missverstanden? Gibt es einen Weg, dies zu erreichen?


EDIT: als eine Frage der Tatsache, wie es funktioniert erwartet, wenn ich p._ wie folgt importieren:

import p._ 
p.print() 

die in der Tat 9 druckt.

Ist dies das richtige Verhalten? Verwenden Sie import als schlechte Idee, wie es klingt? Wie kann ich das umgehen?

+0

Der Grund, dass das Importieren' verhalten wollte p._' funktioniert, weil Sie einfach das 'i' aus der case-Klasse IntPrinter (implizit val i: Int)' in den Geltungsbereich bringen. Aber ... das 'i' ist bereits innerhalb der Klasse" im Umfang "; Sie müssen nichts Spezielles tun, um darauf zuzugreifen. – Destin

Antwort

1

In der Tat ist es das richtige Verhalten. implicit Werte werden nur im aktuellen Bereich gesucht und Aufruf print außerhalb IntPrinter bedeutet, dass es nicht auf dem Klassenumfang (offensichtlich) und der Grund, warum ich import es war.

Der richtige Weg zu tun, was ich wollte: (. Weil printProxy innen IntPrinter ‚s Umfang)

case class IntPrinter(implicit val i: Int) { 
    def print()(implicit i: Int) = println(i) 
    def printProxy() = print() 
} 

Und dann ruft p.printProxy verhält sich wie ich es

1

Ich bin mir nicht sicher, ob ich das verstehe. Warum brauchen Sie hier überhaupt etwas? Es scheint, dass Sie könnte genauso gut tun:

scala> case class IntPrinter(i: Int) { def print() = println(i) } 
defined class IntPrinter 

scala> val p = IntPrinter(9) 
p: IntPrinter = IntPrinter(9) 

scala> p.print() 
9 

oder, wenn man wirklich Verwendung für IntPrinter nehmen eine implizite haben:

scala> case class IntPrinter(implicit val i: Int) { def print() = println(i) } 
defined class IntPrinter 

scala> val p = IntPrinter()(9) 
p: IntPrinter = IntPrinter(9) 

scala> p.print() 
9 

Grundsätzlich sind in diesem Fall müssen legen Sie nicht, dass es ist zweimal implizit; Wenn Sie es das erste Mal implizit deklariert haben, hat das i zu einem Mitglied der Klasse gemacht, sodass Sie im gesamten Rest der Klasse weiter darauf verweisen können - genau wie bei jedem anderen Datenelement einer Klasse.

+0

Es ist nur ein minimales Beispiel, die Art, wie ich es verwenden möchte, ist komplizierter. Es ist jedenfalls meine Schuld, dass ich nicht ausdrücken konnte, was ich zu erreichen versuchte (siehe meine Antwort). – kaoD

+0

@kaoD Aber deine Antwort macht immer noch keinen Sinn. Warum sollten Sie sich mit 'printProxy' beschäftigen? Warum greifen Sie nicht einfach auf das "i" zu, das Sie bereits beim Erstellen des Objekts angegeben haben? Das ist alles, was 'printProxy' sowieso macht ... – Destin

+0

Weil, wie gesagt, dies nur ein minimales Beispiel dessen ist, was ich erreichen wollte.Ich möchte syntaktischen Zucker auf einem DSL I Gebäude bin, die transparent einige implizite Parameter behandeln soll (und geben sie um neue Instanzen von sich selbst zu transparent), ohne sie explizit den Zugriff (für Vernunft und Klarheit des Codes.) Der Wert muss nur zugegriffen werden, in ein paar Fälle, während der Rest der Zeit muss es unsichtbar sein (wie gesagt, ich erwarte DSL Klarheit.) – kaoD

Verwandte Themen