In Scala funktioniert implizit wie folgt :
Konverter
Parameterwert Injektor
Es gibt 3 Arten der impliziten Verwendung
Implizite Typkonvertierung : Konvertiert die fehlererzeugende Zuordnung in den beabsichtigten Typ
val x: String = "1"
val y: Int = x
String ist nicht der Untertyp von Int , daher tritt ein Fehler in Zeile 2 auf. Um den Fehler zu beheben, sucht der Compiler nach einer solchen Methode im Bereich, die ein implizites Schlüsselwort enthält, einen String als Argument verwendet und einen Int zurückgibt .
damit
implicit def z(a:String):Int = 2
val x :String = "1"
val y:Int = x // compiler will use z here like val y:Int=z(x)
println(y) // result 2 & no error!
Implizite Empfängerkonvertierung : Wir rufen im Allgemeinen die Eigenschaften des Empfängeraufrufobjekts auf, z. Methoden oder Variablen. Um eine Eigenschaft von einem Empfänger aufzurufen, muss die Eigenschaft Mitglied der Klasse / des Objekts dieses Empfängers sein.
class Mahadi{
val haveCar:String ="BMW"
}
class Johnny{
val haveTv:String = "Sony"
}
val mahadi = new Mahadi
mahadi.haveTv // Error happening
Hier wird mahadi.haveTv einen Fehler erzeugen. Weil der Scala-Compiler zuerst nach der haveTv- Eigenschaft für den Mahadi- Empfänger sucht . Es wird nicht finden. Zweitens wird nach einer Methode im Gültigkeitsbereich mit implizitem Schlüsselwort gesucht, die das Mahadi-Objekt als Argument verwendet und das Johnny-Objekt zurückgibt . Aber es hat hier nicht. Es wird also ein Fehler entstehen . Aber das Folgende ist in Ordnung.
class Mahadi{
val haveCar:String ="BMW"
}
class Johnny{
val haveTv:String = "Sony"
}
val mahadi = new Mahadi
implicit def z(a:Mahadi):Johnny = new Johnny
mahadi.haveTv // compiler will use z here like new Johnny().haveTv
println(mahadi.haveTv)// result Sony & no error
Implizite Parameterinjektion : Wenn wir eine Methode aufrufen und ihren Parameterwert nicht übergeben, verursacht dies einen Fehler. Der Scala-Compiler funktioniert folgendermaßen - zuerst wird versucht, einen Wert zu übergeben, es wird jedoch kein direkter Wert für den Parameter abgerufen.
def x(a:Int)= a
x // ERROR happening
Zweitens , wenn die Parameter jedes implizites Schlüsselwort hat , wird es für jeden aussieht val im Rahmen , die die haben gleiche Art von Wert. Wenn nicht, wird es Fehler verursachen.
def x(implicit a:Int)= a
x // error happening here
Slove dieses Problem Compiler für eine aussieht implizite val den mit Typ Int , weil der Parameter a hat implizites Schlüsselwort .
def x(implicit a:Int)=a
implicit val z:Int =10
x // compiler will use implicit like this x(z)
println(x) // will result 10 & no error.
Ein anderes Beispiel:
def l(implicit b:Int)
def x(implicit a:Int)= l(a)
wir können es auch schreiben wie-
def x(implicit a:Int)= l
Da L hat einen impliziten Parameter und im Rahmen der körpereigenen Methode x gibt es einen impliziten lokalen Variable ( Parameter sind lokale Variablen ) ein , die die Parameter der ist , x , so in dem Körper der x - Methode der Methodensignatur Ls impliziter Argumentwert ist durch die eingereichten x - Methode der lokalen impliziten Variable (Parameter) a
implizit .
Damit
def x(implicit a:Int)= l
wird im Compiler so sein
def x(implicit a:Int)= l(a)
Ein anderes Beispiel:
def c(implicit k:Int):String = k.toString
def x(a:Int => String):String =a
x{
x => c
}
Dies führt zu Fehlern, da c in x {x => c} eine explizite Wertübergabe im Argument oder einen impliziten Wert im Gültigkeitsbereich erfordert .
Wir können also den Parameter des Funktionsliteral explizit implizit machen, wenn wir die Methode x aufrufen
x{
implicit x => c // the compiler will set the parameter of c like this c(x)
}
Dies wurde in der Aktionsmethode von Play-Framework verwendet
in view folder of app the template is declared like
@()(implicit requestHreader:RequestHeader)
in controller action is like
def index = Action{
implicit request =>
Ok(views.html.formpage())
}
Wenn Sie den Anforderungsparameter nicht explizit als implizit erwähnen, müssen Sie geschrieben worden sein.
def index = Action{
request =>
Ok(views.html.formpage()(request))
}