Basta ya de investigar por internet ya que estás al espacio correcto, tenemos la solución que necesitas encontrar pero sin complicaciones.
Solución:
Explicaré los principales casos de uso de implícitos a continuación, pero para obtener más detalles, consulte el capítulo correspondiente de Programación en Scala.
Parámetros implícitos
La lista final de parámetros de un método se puede marcar implicit
, lo que significa que los valores se tomarán del contexto en el que se llaman. Si no hay un valor implícito del tipo correcto en el alcance, no se compilará. Dado que el valor implícito debe resolverse en un solo valor y para evitar choques, es una buena idea hacer que el tipo sea específico para su propósito, por ejemplo, no requiera que sus métodos encuentren un valor implícito Int
!
ejemplo:
// probably in a library
class Prefixer(val prefix: String)
def addPrefix(s: String)(implicit p: Prefixer) = p.prefix + s
// then probably in your application
implicit val myImplicitPrefixer = new Prefixer("***")
addPrefix("abc") // returns "***abc"
Conversiones implícitas
Cuando el compilador encuentra una expresión del tipo incorrecto para el contexto, buscará una expresión implícita Function
valor de un tipo que le permitirá comprobar el tipo. Entonces, si un A
es necesario y encuentra un B
, buscará un valor implícito de tipo B => A
en alcance (también comprueba algunos otros lugares como en el B
y A
objetos complementarios, si existen). Ya que def
s se puede “expandir eta” en Function
objetos, un implicit def xyz(arg: B): A
también lo hará.
Entonces, la diferencia entre sus métodos es que el marcado implicit
será insertado por usted por el compilador cuando un Double
se encuentra pero un Int
es requerido.
implicit def doubleToInt(d: Double) = d.toInt
val x: Int = 42.0
funcionará igual que
def doubleToInt(d: Double) = d.toInt
val x: Int = doubleToInt(42.0)
En el segundo hemos insertado la conversión manualmente; en el primero, el compilador hizo lo mismo automáticamente. La conversión es necesaria debido a la anotación de tipo en el lado izquierdo.
Con respecto a su primer fragmento de Play:
Las acciones se explican en esta página de la documentación de Play (consulte también los documentos API). Tu estas usando
apply(block: (Request[AnyContent]) ⇒ Result): Action[AnyContent]
sobre el Action
objeto (que es el compañero del rasgo del mismo nombre).
Por lo tanto, debemos proporcionar una función como argumento, que se puede escribir como literal en la forma
request => ...
En una función literal, la parte antes de la =>
es una declaración de valor y se puede marcar implicit
si quieres como en cualquier otro val
declaración. Aquí, request
no tiene que estar marcado implicit
para que esto escriba check, pero al hacerlo será disponible como valor implícito para cualquier método que pueda necesitarlo dentro de la función (y, por supuesto, también se puede usar explícitamente). En este caso particular, esto se ha hecho porque el bindFromRequest
método en la clase Form requiere un implícito Request
argumento.
ADVERTENCIA: contiene sarcasmo juiciosamente! YMMV …
La respuesta de Luigi es completa y correcta. Este es solo para extenderlo un poco con un ejemplo de cómo puede gloriosamente usarlo en exceso. implicitos, como sucede con bastante frecuencia en los proyectos de Scala. En realidad, con tanta frecuencia, es probable que incluso pueda encontrarlo en uno de los “Mejores prácticas” guías.
object HelloWorld
case class Text(content: String)
case class Prefix(text: String)
implicit def String2Text(content: String)(implicit prefix: Prefix) =
Text(prefix.text + " " + content)
def printText(text: Text): Unit =
println(text.content)
def main(args: Array[String]): Unit =
printText("World!")
// Best to hide this line somewhere below a pile of completely unrelated code.
// Better yet, import its package from another distant place.
implicit val prefixLOL = Prefix("Hello")
En scala implícita funciona como:
Convertidor
Inyector de valor de parámetro
Método de extensión
Hay 3 tipos de uso de implícito
-
Conversión de tipo implícita : Convierte la asignación que produce el error en el tipo previsto
val x :String = "1" val y:Int = x
Cuerda No es el subtipo de Int , por lo que el error ocurre en la línea 2. Para resolver el error, el compilador buscará un método de este tipo en el alcance que tenga una palabra clave implícita y tome una Cuerda como argumento y devuelve un En t .
asi que
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 de receptor implícita: Generalmente, por el 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 el 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 de Scala buscará primero el haveTv propiedad a Mahadi receptor. No encontrará. En segundo lugar, buscará un método en el alcance que tenga palabra clave implícita que toma Objeto Mahadi como argumento y devoluciones Objeto de Johnny. Pero no tiene aquí. Entonces creará 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 de parámetros implícitamente: Si llamamos a un método y no pasamos su valor de parámetro, causará un error. El compilador de 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
En segundo lugar, si el parámetro tiene alguna palabra clave implícita, buscará cualquier val en el alcance que tienen el el mismo tipo de valor. Si no se obtiene, se producirá un error.
def x(implicit a:Int)= a
x // error happening here
Para resolver este problema, el compilador buscará un val implícito tener el tipo de Int porque el parámetro a tiene 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
Porque l tiene un parámetro implícito y en el alcance de cuerpo del método x, hay un variable local implícita(los parámetros son variables locales) a que es el parámetro de X, entonces en el cuerpo de xmétodo la firma del método valor del argumento implícito de l es archivado por el Variable implícita local del método x (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
Causará error, porque C en x x => c Necesita pasar explícitamente un valor en un argumento o un valor implícito en alcance.
Entonces podemos hacer que la función sea literal parámetro 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 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, debe haber sido escrito-
def index = Action
request =>
Ok(views.html.formpage()(request))
- Método de extensión
Piense, queremos agregar un nuevo método con el objeto Integer. El nombre del método será meterToCm,
> 1 .meterToCm
res0 100
para hacer esto, necesitamos crear una clase implícita dentro de un objeto / clase / rasgo. Esta clase no puede ser una clase de caso.
object Extensions
implicit class MeterToCm(meter:Int)
def meterToCm=
meter*100
Nota la clase implícita solo tomará un parámetro de constructor.
Ahora importe la clase implícita en el alcance que desea usar
import Extensions._
2.meterToCm // result 200
Valoraciones y comentarios
Tienes la opción de añadir valor a nuestra información participando con tu experiencia en los comentarios.