330 votes

Comprendre implicite dans Scala

J'ai été faire mon chemin à travers la Scala playframework tutoriel et je suis tombé sur cet extrait de code qui m'avait intrigué:

def newTask = Action { implicit request =>
taskForm.bindFromRequest.fold(
        errors => BadRequest(views.html.index(Task.all(), errors)),
        label => {
          Task.create(label)
          Redirect(routes.Application.tasks())
        } 
  )
}

J'ai donc décidé d'enquêter et suis tombé sur ce post.

Je ne comprends toujours pas.

Quel est la différence entre ceci:

implicit def double2Int(d : Double) : Int = d.toInt

et..

def double2IntNonImplicit(d : Double) : Int = d.toInt

autre que le fait évident qu'ils ont différents noms de méthode.

Quand dois-je utiliser implicite et pourquoi?

Merci à l'avance.

428voto

Luigi Plinge Points 23552

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 defs 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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X