W scala niejawne działa jako :
Przetwornik
Wtryskiwacz wartości parametru
Istnieją 3 rodzaje zastosowania Implicit
Konwersja typu niejawnie : Konwertuje błąd powodujący przypisanie błędu na zamierzony typ
val x: String = "1"
val y: Int = x
String nie jest podtypem Int , więc błąd występuje w wierszu 2. Aby rozwiązać błąd, kompilator wyszuka taką metodę w zakresie, który zawiera niejawne słowo kluczowe i przyjmuje String jako argument i zwraca Int .
więc
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!
Niejawna konwersja odbiornika : generalnie na podstawie właściwości obiektu wywołania odbiorcy, np. metody lub zmienne. Tak więc, aby wywołać dowolną właściwość przez odbiorcę, właściwość musi być członkiem klasy / obiektu tego odbiorcy.
class Mahadi{
val haveCar:String ="BMW"
}
class Johnny{
val haveTv:String = "Sony"
}
val mahadi = new Mahadi
mahadi.haveTv // Error happening
Tutaj mahadi.haveTv spowoduje błąd. Ponieważ kompilator Scala najpierw poszuka właściwości haveTv w odbiorniku Mahadi . Nie znajdzie. Po drugie, będzie szukał metody o zasięgu z niejawnym słowem kluczowym, która przyjmuje obiekt Mahadi jako argument i zwraca obiekt Johnny . Ale tu nie ma. To spowoduje błąd . Ale następujące jest w porządku.
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
Niejawne wprowadzanie parametrów : jeśli wywołamy metodę i nie przekażemy jej wartości parametru, spowoduje to błąd. Kompilator scala działa w ten sposób - najpierw spróbuje przekazać wartość, ale nie otrzyma bezpośredniej wartości parametru.
def x(a:Int)= a
x // ERROR happening
Po drugie, jeśli parametr ma żadnych niejawny słowa kluczowego będzie wyglądać za każdym val w zakresie , które mają ten sam typ wartości. Jeśli nie dostaniesz spowoduje błąd.
def x(implicit a:Int)= a
x // error happening here
Aby spowolnić ten problem, kompilator szuka niejawnej wartości typu Int, ponieważ parametr a ma niejawne słowo kluczowe .
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.
Inny przykład:
def l(implicit b:Int)
def x(implicit a:Int)= l(a)
możemy też napisać jak
def x(implicit a:Int)= l
Ponieważ l ma niejawny parametr oraz w zakresie treści metody x , istnieje niejawna zmienna lokalna ( parametry to zmienne lokalne ) a, która jest parametrem x , więc w treści metody x wartość domyślnego argumentu l podpisu metody wynosi złożony przez lokalną zmienną niejawny x metody badaniem (parametrów) a
w sposób dorozumiany .
Więc
def x(implicit a:Int)= l
będzie w takim kompilatorze
def x(implicit a:Int)= l(a)
Inny przykład:
def c(implicit k:Int):String = k.toString
def x(a:Int => String):String =a
x{
x => c
}
może to być przyczyną błędów, ponieważ C w X = {x> c} potrzebuje wyraźnie wartości pominięciem argument lub utajonego Val zakres .
Możemy więc uczynić parametr literału funkcji jawnie niejawnym, gdy wywołujemy metodę x
x{
implicit x => c // the compiler will set the parameter of c like this c(x)
}
Zostało to wykorzystane w metodzie akcji 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())
}
jeśli nie wymieniasz jawnie parametru żądania jako jawnego, to musisz mieć napisane-
def index = Action{
request =>
Ok(views.html.formpage()(request))
}