Je vais vous expliquer les principaux cas d'utilisation des implicites ci-dessous, mais pour plus de détail, voir le chapitre correspondant de la Programmation Scala.
Implict paramètres
Le dernier paramètre de la liste sur une méthode peut être marquée implicit
, ce qui signifie que les valeurs seront prises à partir du contexte dans lequel ils sont appelés. Si il n'y a pas de valeur implicite du type de droit de portée, il ne compile pas. Depuis l'implicite de la valeur doit correspondre à une valeur unique et éviter les affrontements, c'est une bonne idée de faire le type spécifique de son objet, par exemple, ne pas besoin de vos méthodes pour trouver un implicite Int
!
exemple:
// 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"
Les conversions implicites
Lorsque le compilateur trouve une expression de type incorrect dans le contexte, il va chercher un implicite Function
de la valeur d'un type qui va lui permettre de typecheck. Donc, si un A
est requis et il trouve un B
,, il va chercher une valeur implicite de type B => A
portée (il vérifie également dans quelques autres endroits, comme dans l' B
et A
compagnon objets, s'ils existent). Depuis def
s peut être "l'eta-étendu", en Function
objets, implicit def xyz(arg: B): A
feront ainsi.
Donc, la différence entre vos méthodes est que l'une marquée implicit
seront insérés pour vous par le compilateur lorsqu'un Double
est trouvé mais un Int
est requis.
implicit def doubleToInt(d: Double) = d.toInt
val x: Int = 42.0
travaille de la même façon que
def doubleToInt(d: Double) = d.toInt
val x: Int = doubleToInt(42.0)
Dans la seconde, nous avons inséré la conversion manuellement; dans la première, le compilateur fait la même automatiquement. La conversion est nécessaire en raison du type d'annotation sur le côté gauche.
Concernant votre premier extrait de Jouer:
Les Actions sont expliquées sur cette page de la documentation (voir aussi les docs de l'API). Vous utilisez
apply(block: (Request[AnyContent]) ⇒ Result): Action[AnyContent]
sur l' Action
objet (qui est le compagnon de l'traits de caractère du même nom).
Nous avons donc besoin d'une Fonction comme argument, qui peut être écrit comme un littéral dans la forme
request => ...
Dans un littéral de fonction, la partie avant de l' =>
est une déclaration de valeur, et peut être marquée implicit
si vous le souhaitez, tout comme dans toute autre val
déclaration. Ici, request
ne pas avoir à être marquée implicit
pour ce type de vérification, mais ce faisant, il sera disponible en tant que valeur implicite pour toutes les méthodes qui pourraient en avoir besoin au sein de la fonction (et bien sûr, il peut être utilisé explicitement). Dans ce cas particulier, cela a été fait parce que l' bindFromRequest
méthode sur le Formulaire de classe implique un implicite Request
argument.