2016-09-22 3 views
2

Je suis presque complètement nouveau à Scala, quelques mois plus tard. J'ai remarqué quelques signatures sauvages. J'ai travaillé à travers les génériques avec contrapositive/copositive/extensions/invariance, et la plupart des bases. Cependant, je continue de trouver certaines signatures de méthode un peu confuses. Alors que je trouve des exemples et que je sais ce que produisent les signatures, je suis encore un peu perplexe quant à certaines fonctionnalités. Googling mes questions m'a laissé sans réponses. J'ai l'idée générale que les gens aiment battre les CS 1 de base à mort. J'ai même essayé de trouver des réponses sur le site Web de la scala. Peut-être que je reformule mal des choses comme «signature de méthode étendue» et «définition de l'utilisation d'une fonction dans une signature scala». Quelqu'un peut-il expliquer cette signature?Sur les signatures de la méthode Scala étendue

futureUsing[I <: Closeable, R](resource: I)(f: I => Future[R])(implicit ec: ExecutionContext):Future[R] 

Je pense que, après les génériques initiaux et la déclaration de paramètre avec un paramètre de type I, le corps est défini et la dernière partie est des objets spécifiques à la fonction ou qui doit être cherchée dans un champ implicite (Sont-ils détruits par la suite?). Quelqu'un peut-il mettre en page une signature de méthode étendue afin que je sache quel code j'utilise? Y a-t-il un ordre particulier dans lequel les deux dernières parties doivent être?

Remarque

Après un tas plus la recherche, j'ai trouvé quelques réponses valides je peux jeter ensemble:

-Scala - Currying and default arguments

-why in Scala a function type needs to be passed in separate group of arguments into a function

Il n'y a pas d'ordre de jeu juste Cela implique qu'il doit être le dernier. Le placement concerne la dépendance qui coule de gauche à droite en tant que personne dans la liste dans l'une des réponses ci-dessus. Pourquoi je ne peux pas avoir d'implicits d'abord et tout ce qui dépend d'eux après est bizarre puisque ne rien avoir disponible provoque une erreur et les choses vont probablement dépendre d'un implicite donné.

Cependant, je suis encore un peu confus. Lors de la spécification f: I => Future [R], et avoir besoin de fournir le dernier argument, il serait faire semblant LETs être une implicite, aurais-je besoin de faire quelque chose comme:

futureUsing(resourceOfI)({stuff => doStuff(stuff)})(myImplicit) 

Est-ce même correct?

Puis-je faire:

futureUsing(resourceOfI)(myImplicit)({stuff => doStuff(stuff)}) 

Pourquoi? Je suis vraiment en train d'essayer de comprendre les raisons sous-jacentes plutôt qu'un simple oui ou non.

Note finale

Je viens de trouver cette réponse. Il semble que l'ordre ne peut pas être changé. S'il vous plait corrigez moi si je me trompe.

Scala: Preference among overloaded methods with implicits, currying and defaults

Répondre

4

Quelqu'un peut-il expliquer cette signature?

futureUsing[I <: Closeable, R] 

futureUsing travaille avec deux types distincts (deux paramètres de type). Nous ne savons pas exactement quels types ils sont, mais nous appellerons un I (entrée), qui est un (ou dérivé de) Closable, et l'autre R (résultat).

(resourse: I) 

Le 1er argument de cari à futureUsing est de type I. Nous l'appellerons resourse.

(f: I => Future[R]) 

Le 2ème argument de cari, f, est une fonction qui prend un argument de type I et renvoie une Future qui (éventuellement) contiennent quelque chose du type R.

(implicit ec: ExecutionContext) 

Le 3ème argument de cari, ec, est de type ExecutionContext. Cet argument est implicite, ce qui signifie que s'il n'est pas fourni lorsque futureUsing est invoqué, le compilateur recherchera un ExecutionContext dans la portée qui a été déclarée implicit et il tirera cela comme troisième argument.

:Future[R] 

futureUsing renvoie un Future qui contient le résultat de type R.


Y at-il un ordre spécifique à ce sujet?

Les paramètres implicites doivent être les derniers (les plus à droite) des paramètres. A part cela, non, resourse et f auraient pu être déclarés dans l'un ou l'autre ordre. Lorsqu'il est invoqué, bien sûr, l'ordre des arguments doit correspondre à l'ordre déclaré dans la définition.

Ai-je besoin ... d'impliquer pour glisser?

Dans le cas de l'utilisation ExecutionContext laisser du compilateur ce qui est disponible à partir import scala.concurrent.ExecutionContext. Seulement dans de rares occasions, vous auriez besoin de quelque chose de différent.

... Comment serait Scala utiliser le 2ème argument de cari ...

Dans le corps de futureUsing j'attendre à voir f(resourse). f prend un argument de type I. resourse est de type I. f renvoie Future[R] et futureUsing de sorte que la ligne f(resourse) peut être la dernière instruction dans le corps de futureUsing.

+0

Donc, y a-t-il un ordre spécifique à cela, je comprends ce qu'ils font. Après la saisie des paramètres initiaux, ai-je besoin (apport de la fonction du corps) (implique de faire glisser)? Puis-je faire par exemple def futureUsing [E, V] (par: E) (ec implicite: ExecutionContext) (f: E => Future [V]): Future [V] = Future {..... Aussi, comment Scala utiliserait-il le second argument curry (f: I => Future [R]) sans l'avoir comme implicite ou spécifié. –