Explicaré los principales casos de uso de implicitos a continuación, pero para más detalles, vea el relevant chapter of Programming in Scala.
parámetros implícitos
La lista de parámetros final sobre un método se pueden marcar implicit
, que significa que los valores se toman a partir del contexto en el que se les llama. 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 único valor y para evitar conflictos, es una buena idea hacer que el tipo sea específico para su propósito, p. no requiera sus métodos para encontrar un 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, se buscará un valor implícito Function
de un tipo que le permitirá para tipear Entonces, si se requiere un A
y encuentra un B
, buscará un valor implícito de tipo B => A
en el alcance (también verifica otros lugares como en los objetos complementarios B
y A
, si existen). Como def
s pueden ser "expandidos eta" en objetos Function
, también funcionará un implicit def xyz(arg: B): A
.
Así que la diferencia entre sus métodos es que el compilador insertará uno marcado implicit
cuando se encuentre un Double
pero se requiere un Int
.
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 la segunda 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.
En cuanto a su primer fragmento de Juego:
acciones se explican en this page de la documentación de reproducción (véase también API docs). Está utilizando
apply(block: (Request[AnyContent]) ⇒ Result): Action[AnyContent]
en el objeto Action
(que es el compañero con el rasgo del mismo nombre).
por lo que necesitamos para suministrar una función como argumento, que puede escribirse como un literal en forma
request => ...
En un literal de la función, la parte antes del =>
es una declaración de valor, y puede ser marcó implicit
si lo desea, al igual que en cualquier otra declaración val
. Aquí, request
no se tiene que marcar implicit
para que este tipo de verificación, pero al hacerlo será disponible como un valor implícito para cualquier método que pueda necesitarlo dentro de la función (y, por supuesto, puede ser utilizado explícitamente también). En este caso particular, esto se ha hecho porque el método bindFromRequest
en la clase Form requiere un argumento implícito Request
.
Gracias por la respuesta. El enlace para el capítulo 21 es realmente increíble. Lo aprecio. – Clive
Solo para agregar esto, el siguiente video brinda una excelente explicación de las implicaciones más algunas otras características de scala http://www.youtube.com/watch?v=IobLWVuD-CQ – Shakti