En scala funciona implícitamente como :
Convertidor
Valor del parámetro inyector
Hay 3 tipos de uso de implícito
Conversión de tipo implícita : convierte el error que produce la asignación en el tipo deseado
val x: String = "1"
val y: Int = x
String no es el subtipo de Int , por lo que se produce un error en la línea 2. Para resolver el error, el compilador buscará dicho método en el ámbito que tenga una palabra clave implícita y tome un String como argumento y devuelva un Int .
entonces
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!
Conversión implícita del receptor : generalmente, por receptor, llamamos a las propiedades del objeto, por ejemplo. métodos o variables. Entonces, para llamar a cualquier propiedad por un receptor, la propiedad debe ser miembro de la clase / objeto de ese receptor.
class Mahadi{
val haveCar:String ="BMW"
}
class Johnny{
val haveTv:String = "Sony"
}
val mahadi = new Mahadi
mahadi.haveTv // Error happening
Aquí mahadi.haveTv producirá un error. Debido a que el compilador Scala buscará primero la haveTv propiedad a Mahadi receptor. No lo encontrarás. En segundo lugar, buscará un método en el alcance que tenga una palabra clave implícita que tome el objeto Mahadi como argumento y devuelva el objeto Johnny . Pero no tiene aquí. Entonces creará un error . Pero lo siguiente está bien.
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
Inyección implícita de parámetros : si llamamos a un método y no pasamos su valor de parámetro, causará un error. El compilador scala funciona así: primero intentará pasar el valor, pero no obtendrá ningún valor directo para el parámetro.
def x(a:Int)= a
x // ERROR happening
Segundo, si el parámetro tiene alguna palabra clave implícita, buscará cualquier valor en el alcance que tenga el mismo tipo de valor. Si no lo consigue, causará un error.
def x(implicit a:Int)= a
x // error happening here
Para resolver este problema, el compilador buscará un valor implícito que tenga el tipo de Int porque el parámetro a tiene una palabra clave implícita .
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.
Otro ejemplo:
def l(implicit b:Int)
def x(implicit a:Int)= l(a)
también podemos escribirlo como
def x(implicit a:Int)= l
Debido a que l tiene un parámetro implícito y dentro del alcance del cuerpo del método x , existe una variable local implícita (los parámetros son variables locales ) a, que es el parámetro de x , por lo que en el cuerpo del método x el valor de argumento implícito de la firma del método l es presentada por la variable de del método local x implícita (parámetro) a
implícitamente .
Entonces
def x(implicit a:Int)= l
estará en un compilador como este
def x(implicit a:Int)= l(a)
Otro ejemplo:
def c(implicit k:Int):String = k.toString
def x(a:Int => String):String =a
x{
x => c
}
que causará error, porque c en x {x => c} necesita explícitamente el valor de paso en el argumento o val implícita en su alcance .
Entonces podemos hacer que el parámetro de la función literal sea explícitamente implícito cuando llamamos al método x
x{
implicit x => c // the compiler will set the parameter of c like this c(x)
}
Esto se ha utilizado en el método de acción de 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())
}
si no menciona el parámetro de solicitud como implícito explícitamente, entonces debe haber sido escrito
def index = Action{
request =>
Ok(views.html.formpage()(request))
}