“à l'aide de la fonction”
J'ai défini " à l'aide de la fonction comme suit:
def using[A, B <: {def close(): Unit}] (closeable: B) (f: B => A): A =
try { f(closeable) } finally { closeable.close() }
Je peux l'utiliser comme ça:
using(new PrintWriter("sample.txt")){ out =>
out.println("hellow world!")
}
maintenant, je suis curieux de savoir comment le définir à l'aide de la fonction de prendre n'importe quel nombre de paramètres, et être en mesure d'y accéder séparément:
using(new BufferedReader(new FileReader("in.txt")), new PrintWriter("out.txt")){ (in, out) =>
out.println(in.readLIne)
}
- Dupliquer: stackoverflow.com/questions/2207425/...
- Ne
closeable.close()
à l'intérieur d'untry
, ou vous pouvez le masque d'exceptions dansf(closeable)
. - Connexes stackoverflow.com/q/7602804/243233
- Généralement, j'ai le nom il 'clôture' non seulement parce qu'il utilise mais surtout, ferme le flux alors que la vraie "à l'aide" est réservé pour de simples
def using[T](t: T)(f: T => Unit): T = {f(t) ; t}
, ce qui est utile dans le cas où vous obtenez la valeur et que vous voulez revenir comme un résultat, mais de faire quelque chose avant queval v = obtain; printlnt(v) ; v
. Donc, vous écrivez, passThrough(obtenir){println}. - J'ai mis en place une version différente de "l'aide", qui est plus robuste et utilise Essayer de capturer des exceptions: stackoverflow.com/a/34277491/501113
Vous devez vous connecter pour publier un commentaire.
Quelqu'un l'a déjà fait—on appelle Scala BRAS.
Du readme:
De départ
Scala 2.13
, la bibliothèque standard fournit une ressource dédiée utilitaire de gestion:à l'Aide de
.Plus précisément, la
à l'Aide de#Manager
peut être utilisé lorsque vous traitez avec plusieurs ressources.Dans notre cas, nous pouvons gérer les différentes ressources telles que votre
PrintWriter
ouBufferedReader
qu'ils mettent en œuvreAutoCloseable
, afin de pouvoir lire et écrire à partir d'un fichier à l'autre et, n'importe quoi, proche à la fois l'entrée et la sortie de ressources par la suite:J'ai pensé à ce sujet et j'ai pensé que peut-être il y avait une autre façon d'aborder cette question. Voici mon point de vue sur le soutien quel que soit le nombre de paramètres (limité par ce que les tuples à fournir):
Je pense que je vais réutiliser le fait que 22 tuple/catégories de produits ont été écrits dans la bibliothèque... je ne pense pas que cette syntaxe est plus claire que à l'aide de imbriquée
using
(aucun calembour prévu), mais c'était un puzzle intéressant.edit: remplacé le val d'affectation avec
case (in, out, other)
comme suggéré par retronym.x => val (in, out, other) = x
aveccase (in, out, other) =>
Malheureusement, il n'y a pas de support de longueur arbitraire des listes de paramètres arbitraires types standard de Scala.
Vous pourriez être en mesure de faire quelque chose comme ceci avec un couple de modifications de langue (pour permettre la variable de la liste des paramètres à passer comme les hlist; voir ici pour environ 1/3 de ce qui est nécessaire).
Droit maintenant, la meilleure chose à faire est de simplement faire ce Tuple et la Fonction: mettre en œuvre usingN pour autant N que vous en avez besoin.
Deux est assez facile, bien sûr:
Si vous avez besoin de plus, c'est probablement la peine d'écrire quelque chose qui va générer le code source.
finally
dangereux.Voici un exemple qui vous permet d'utiliser la scala pour la compréhension automatique de gestion des ressources en bloc de tout ce qui est java.io.Fermer, mais il pourrait facilement être étendu à travailler pour n'importe quel objet avec une méthode close.
Cette utilisation semble assez proche de l'instruction d'utilisation et vous permet d'avoir autant de ressources défini dans un bloc que vous le souhaitez.
l'aide structurelle de frappe semble un peu exagéré puisque java.lang.AutoCloseable est prédestiné pour l'utilisation:
ou, si vous préférez les méthodes d'extension:
using2 est possible:
mais à mon humble avis assez laid je préfère simplement nid à l'aide de ces instructions dans le code client.
Cette solution n'est pas assez ont la syntaxe que vous désirez, mais je pense que c'est assez proche 🙂
Bien sûr, l'inconvénient est que vous devez taper les types
BufferedReader
etPrintWrter
à l'aide du bloc. Vous pourriez être en mesure d'ajouter un peu de la magie de sorte que vous avez juste besoinList(in, out)
en utilisant multiples par un ou binaire type de limites pour le type A dans l'utilisation.Par la définition de quelques jolies hacky et dangereux conversions implicites vous pouvez avoir à taper
List
(et une autre façon de contourner spécification de types pour les ressources), mais je n'ai pas documenté le détail, car il est trop dangereux de l'OMI.C'est une bonne idée d'abîmer le nettoyage de l'algorithme à partir du chemin d'accès du programme.
Cette solution vous permet d'accumuler des closeables dans un champ.
Le champ d'application de nettoyage va se passer après le bloc est exécuté, ou le champ d'application peut être détachée. Le nettoyage de la portée peut alors être fait plus tard.
De cette façon nous obtenons le même confort sans être limité à un seul thread de programmation.
La classe utilitaire:
L'utilisation:
voici ma solution pour la gestion des ressources de Scala:
J'ai utilisé ce dans de multiples Scala applications, y compris la gestion des ressources Spark exécuteurs testamentaires. et il faut être conscient que nous sommes des autres, même de meilleures façons de gérer les ressources comme dans CatsIO: https://typelevel.org/cats-effect/datatypes/resource.html. si vous êtes ok avec pure FP à la Scala.
pour répondre à votre dernière question, vous pouvez certainement nid de la ressource comme ceci:
cette façon, non seulement que ces ressources sont protégés contre les fuites, ils seront également libérés dans l'ordre correct(comme la pile). même type de comportement de la Ressource Monade de CatsIO.