2016-07-22 19 views
1

In dem folgenden Scala-Snippet ist mein Ziel, Collector { "A" x 123 } für eine Klasse Collector buchstäblich zu schreiben. Der Rumpf dieser anonymen Unterklasse sollte Zugriff auf eine implizite x haben, die innerhalb der Klasse Collector definiert ist. Ich habe versucht, dies über ein Companion-Objekt und einen By-Name-Parameter zu erreichen, aber ohne Erfolg. Für jetzt muss ich new Collector { "A" x 123 } schreiben. Können Sie hier einen Weg finden, das Schlüsselwort new loszuwerden?Scala - Zugreifen auf eine implizite Klasse aus einer anonymen Unterklasse ohne das neue Schlüsselwort

object TestApp extends App { 
    new Collector { "A" x 123 } // works as intended, even without companion object 
    Collector { "A" x 123 } // does not compile because no implicit "x" found 
} 

class Collector { // some class with an individual implicit inner class 
    val coll = ArrayBuffer.empty[String] 
    implicit class MyImplicit(name: String) { def x(i: Int) = coll += s"$name($i)" } 
} 

object Collector { // getting rid of the "new" keyword looses access to MyImplicit 
    def apply(body: => Unit) = new Collector { body } 
} 

Antwort

1

Collector { "A" x 123 } keine anonymen Unterklasse von Collector, es ist nur ein Methodenaufruf erstellen. Sie können also nicht auf Collector Mitglieder zugreifen, implizit oder nicht, im Argument.

+1

Ah, ich sehe, dies bezieht sich nicht einmal auf Implicits, sondern eher auf Closures und by-name Parameter. Und es gibt wahrscheinlich keine Problemumgehung (ohne Makros). Jetzt sehe ich, dass ich versuchte, den Literalkörper '{" A "x 123}' entlang zweier Sprünge in einen anderen Kontext "weiterzuleiten" (von dem ich erwartete, dass er schließlich die freien Variablen band). Aber es funktioniert umgekehrt: * Zuerst * sind alle freien Variablen an der Stelle begrenzt, an der sie buchstäblich geschrieben sind, also selbst wenn eine Schließung umgangen wird, bezieht sie sich immer nur auf ihren ursprünglichen Kontext. –

+0

Ja, genau. –