2017-03-11 3 views
0

Ich erwarte den folgenden Code zum Drucken 1 und 2. Aber ich bekomme default und default. Wenn ich den impliziten Wert mithilfe des auskommentierten Codes explizit weiterleite (?), Sehe ich die gewünschte Ausgabe. Kann mir jemand erklären, wie das funktioniert? Ist das, was ich versuche, unmöglich? Ich bin total neu in Scala. Was soll ich lesen, um das zu verstehen?Wie indirekt übergeben ein implizites Argument

case class Context(id: Option[String]) 
object Context { 
    implicit val context = Context(Some("default")) 
} 

class ToolBuilder (id: String) { 
    implicit val context = Context(Some(id)) 
    def extract() = ToolCreatorA.create() 
} 

case class ToolCreatorA(id: String) 
object ToolCreatorA { 
    def create() = ToolCreator.create() 
    //def create()(implicit context: Context) = ToolCreator.create() 
    object ToolCreator { 
    def create()(implicit context: Context) = context.id.getOrElse("null") 
    } 
} 

object Main { 
    def main(args: Array[String]): Unit = { 
    println(new ToolBuilder("1").extract()) 
    println(new ToolBuilder("2").extract()) 
    } 
} 

Antwort

3

Vom scala documentation of implicit, das sind die beiden Regeln für Wert für einen impliziten Parameter zu bestimmen.

Zuerst sind alle Bezeichner x in Frage, auf die am Punkt des Methodenaufrufs ohne Präfix zugegriffen werden kann und die eine implizite Definition oder einen impliziten Parameter bezeichnen.

Zweitens sind alle Mitglieder von Companion-Modulen des impliziten Parametertyps, die als implizit gekennzeichnet sind, berechtigt.

Also in Ihrem Fall sehen wir zuerst, was passiert, wenn wir def create() = ToolCreator.create() verwenden. Hier finden ToolCreator.create()create Methode des Begleiters Objekt aufrufen ToolCreator, die eine implizite Context def create()(implicit context: Context) = context.id.getOrElse("null")

    erwartet
  1. Jetzt ist unsere erste Regel besagt, dass das Verfahren für eine implizite param in allen Variablen aussehen wird es Zugang, bevor das Verfahren hat Anruf fand statt. Wir sehen, dass zu diesem Zeitpunkt keine implizite Variable verfügbar ist.
  2. Dann ist die zweite Regel, nach einer impliziten Variable im Begleitobjekt des impliziten Typs zu suchen. In unserem Fall ist das Implizit vom Typ Context und wir haben ein Context-Companion-Objekt, das eine nette implizite Variable definiert hat. So wird dieser Wert in der create Methode abgeholt. object Context { implicit val context = Context(Some("default")) }
  3. Nun, wenn wir die def create()(implicit context: Context) = ToolCreator.create() verwenden, diese create-Methode aus dem

    aufgerufen wird class ToolBuilder (id: String) { implicit val context = Context(Some(id)) def extract() = ToolCreatorA.create() }

  4. Wie Sie sehen können, hier vor der create Methode aufgerufen wird, hat es eine Kontextvariable zur Verfügung als implizit verwendet werden. Also wird dieser Wert abgeholt.

Nützliche Links:

  1. Understanding implicit in Scala

  2. http://www.drmaciver.com/2008/03/an-introduction-to-implicit-arguments/

  3. http://www.artima.com/pins1ed/implicit-conversions-and-parameters.html#21.5

+0

so bedeutet dies, dass in meinem Fall mit einem impliziten Parameter sinnlos ist – perreal

+0

es hängt davon ab, ich habe nicht verstanden, Ihre Absicht der Verwendung von implicits. – Tawkir

+0

meine Absicht ist es, die Implementierung von ToolCreatorA für den impliziten Parameter, den ich einführe, transparent zu machen. Der eigentliche Code hat einige Ebenen mehr, bis ich den ToolCreator erreiche – perreal

Verwandte Themen