In Scala funktioniert implizit als :
Konverter
Parameterwert Injektor
Methode der Erweiterung
Es gibt einige Verwendungen von Implicit
-
Implizite Typkonvertierung : Er wandelt die fehlerhafte Zuweisung in den vorgesehenen Typ um
val x :String = "1"
val y:Int = x
Zeichenfolge ist nicht die Subtyp von Int , so dass in Zeile 2 ein Fehler auftritt. Um den Fehler zu beheben, sucht der Compiler nach einer solchen Methode im Anwendungsbereich, die ein implizites Schlüsselwort hat und eine Zeichenfolge als Argument und gibt ein Int .
also
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 : Im Allgemeinen rufen wir mit dem Empfänger die Eigenschaften des Objekts auf, z.B. Methoden oder Variablen. Um also eine Eigenschaft durch einen Empfänger aufzurufen, muss die Eigenschaft ein Mitglied der Klasse/des Objekts des Empfängers sein.
class Mahadi{
val haveCar:String ="BMW"
}
class Johnny{
val haveTv:String = "Sony"
}
val mahadi = new Mahadi
mahadi.haveTv // Error happening
Hier mahadi.haveTv wird einen Fehler erzeugen. Weil der Scala-Compiler zuerst nach dem haveTv Eigenschaft zu mahadi Empfänger. Er wird nicht gefunden. Zweitens wird nach einer Methode im Geltungsbereich gesucht, die implizites Schlüsselwort die dauern Mahadi Objekt als Argument und gibt Johnny Objekt . Aber das ist hier nicht der Fall. Also wird es schaffen Fehler . 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, führt dies zu einem Fehler. Der Scala-Compiler arbeitet so - er versucht zunächst, einen Wert zu übergeben, aber er erhält keinen direkten Wert für den Parameter.
def x(a:Int)= a
x // ERROR happening
Zweitens: Wenn der Parameter ein implizites Schlüsselwort enthält, wird nach einem val で、その Umfang die die gleiche Art von Wert. Wenn nicht, wird es einen Fehler verursachen.
def x(implicit a:Int)= a
x // error happening here
Um dieses Problem zu lösen, sucht der Compiler nach einem impliziter Wert mit der Typ von 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 weiteres Beispiel:
def l(implicit b:Int)
def x(implicit a:Int)= l(a)
können wir es auch so schreiben.
def x(implicit a:Int)= l
Denn l hat eine impliziter Parameter und im Umfang von methode x's körper gibt es eine implizite lokale Variable ( Parameter sind lokale Variablen ) a die der Parameter von x also im Körper von x Methode die Methodensignatur l's impliziter Argumentwert wird von der die lokale implizite Variable (Parameter) der Methode x a
implizit .
Also
def x(implicit a:Int)= l
wird im Compiler wie folgt aussehen
def x(implicit a:Int)= l(a)
Ein weiteres Beispiel:
def c(implicit k:Int):String = k.toString
def x(a:Int => String):String =a
x{
x => c
}
wird es zu einem Fehler führen, weil c en x{x=>c} benötigt explizite Wertübergabe im Argument oder implizite Wertübergabe in Reichweite .
Wir können also die Funktion literal's Parameter ausdrücklich implizit wenn wir die Verfahren x
x{
implicit x => c // the compiler will set the parameter of c like this c(x)
}
Dies wurde verwendet in Aktionsmethode von Play-Framework
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 Anfrageparameter nicht explizit als implizit erwähnen, dann müssen Sie geschrieben worden sein-
def index = Action{
request =>
Ok(views.html.formpage()(request))
}
- Erweiterungsmethode
Denken Sie, wir wollen eine neue Methode mit Integer-Objekt hinzufügen. Der Name der Methode wird meterToCm sein,
> 1 .meterToCm
res0 100
Dazu müssen wir eine implizite Klasse innerhalb eines Objekts/Klasse/Eigenschaft erstellen. Diese Klasse darf keine Fallklasse sein.
object Extensions{
implicit class MeterToCm(meter:Int){
def meterToCm={
meter*100
}
}
}
Beachten Sie die implizite Klasse dauert nur ein Konstruktorparameter .
Importieren Sie nun die implizite Klasse in dem Bereich, den Sie verwenden möchten
import Extensions._
2.meterToCm // result 200