"mit" - Funktion
Ich definiert habe 'über' - Funktion wie folgt:
def using[A, B <: {def close(): Unit}] (closeable: B) (f: B => A): A =
try { f(closeable) } finally { closeable.close() }
Kann ich es verwenden, wie:
using(new PrintWriter("sample.txt")){ out =>
out.println("hellow world!")
}
nun bin ich neugierig, wie definieren Sie 'über' - Funktion, um eine beliebige Anzahl von Parametern, und in der Lage sein, um Ihnen den Zugang separat:
using(new BufferedReader(new FileReader("in.txt")), new PrintWriter("out.txt")){ (in, out) =>
out.println(in.readLIne)
}
- Duplizieren: stackoverflow.com/questions/2207425/...
- Tun
closeable.close()
innerhalb einertry
oder Sie können die Maske Ausnahmen inf(closeable)
. - Im Zusammenhang stackoverflow.com/q/7602804/243233
- In der Regel, ich nenne es 'schließen', weil es nicht nur verwendet, sondern auch wichtig schließt den stream in der Erwägung, dass true 'verwenden' reserviert für einfache
def using[T](t: T)(f: T => Unit): T = {f(t) ; t}
, die nützlich in Fällen, wo Sie bekommen Wert und wollen es zurück, als ein Ergebnis, sondern etwas tun, bevor, dassval v = obtain; printlnt(v) ; v
. Also, du schreibst, Pass-through(zu erhalten){println}. - Implementiert habe ich eine andere version von 'Nutzung', die ist robuster und nutzt zu erfassen Versuchen-Ausnahmen: stackoverflow.com/a/34277491/501113
Du musst angemeldet sein, um einen Kommentar abzugeben.
Jemand hat dies bereits getan—es heißt Scala ARM.
Aus der readme:
Ich habe darüber nachgedacht und ich dachte, vielleicht gab es einen anderen Weg, um diese Probleme anzugehen. Hier ist mein nehmen auf die Unterstützung von "eine beliebige Anzahl" der Parameter (begrenzt durch das, was Tupeln liefern):
Ich glaube, ich bin die Wiederverwendung der Tatsache, dass 22 Tupel/Produkt-Klassen geschrieben wurden, in der Bibliothek... ich glaube nicht, dass diese syntax ist übersichtlicher als mit verschachtelte
using
(kein Wortspiel beabsichtigt), aber es war ein Interessantes Rätsel.edit: ersetzt das val Belegung mit
case (in, out, other)
wie vorgeschlagen von retronym.x => val (in, out, other) = x
mitcase (in, out, other) =>
Leider gibt es nicht die Unterstützung für willkürliche-Länge-parameter-Listen mit beliebigen Typen in der standard-Scala.
Könnten Sie in der Lage sein, etwas zu tun, wie hier ein paar der Sprache der änderungen (zu ermöglichen variable parameter-Listen übergeben werden, da HLists; siehe hier für etwa 1/3 von dem, was benötigt wird).
Right now, die beste Sache zu tun, nur tun, was Tupel und Funktion zu tun: implementieren usingN für wie viele N, wie Sie benötigen.
Beiden ist einfach genug, natürlich:
Wenn du mehr brauchst, lohnt es sich wahrscheinlich, etwas zu schreiben, dass generieren werde den source-code.
finally
unsicher.Hier ist ein Beispiel, in dem Sie die scala für das Verständnis, wie eine automatische Ressourcen-management-block für jedes Element, das eine java.io.Verschließbar, aber es könnte leicht erweitert werden, um für jedes Objekt mit einer close-Methode.
Diese Nutzung scheint ziemlich nah an die using-Anweisung und erlaubt Sie zu leicht zu haben, wie viele Ressourcen in einem block, wie Sie möchten.
Diese Lösung nicht ganz haben die syntax, die Sie wünschen, aber ich denke, es ist nah genug 🙂
Natürlich der Nachteil ist, Sie haben zu geben die Typen
BufferedReader
undPrintWrter
im using-block. Sie können möglicherweise fügen Sie etwas Magie, so dass Sie brauchen nurList(in, out)
mithilfe mehrere ORed Art Grenzen für Typ A in Verwendung.Durch die Definition einige ziemlich hacky und gefährlich implizite Konvertierungen, die Sie bekommen können, um mit Typ
List
(und anderen Weg, um mit der Angabe von Typen für die Ressourcen), aber ich habe nicht dokumentiert, das detail, als es ist zu gefährlich, IMO.Ist es eine gute Idee, um detatch der cleanup-Algorithmus aus dem Programm Pfad.
Dieser Lösung können Sie sammeln closeables in einem Bereich.
Den Umfang der Bereinigung passieren wird, nachdem sich der block ausgeführt wird, oder der Bereich kann abgetrennt werden. Die Reinigung der Rahmen kann dann später erfolgen.
Diese Weise erhalten wir den gleichen Komfort ohne Beschränkung auf single-thread-Programmierung.
Die utility-Klasse:
Die Verwendung:
mithilfe von struktureller Typisierung scheint ein wenig übertrieben, da java.lang.AutoCloseable ist prädestiniert für den Einsatz:
oder wenn Sie es bevorzugen extension Methoden:
using2 ist möglich:
aber imho ziemlich hässlich - ich würde lieber einfach verschachteln Sie diese using-Anweisung in den client-code.
Ab
Scala 2.13
die standard-Bibliothek bietet eine dedizierte Ressource management utility:Mit
.Genauer gesagt, die
Mit#Manager
kann verwendet werden, wenn es mit mehreren Ressourcen.In unserem Fall können wir die Verwaltung verschiedener Ressourcen wie Ihre
PrintWriter
oderBufferedReader
, wie Sie implementieren beideAutoCloseable
, um Lesen und schreiben aus einer Datei in eine andere, und, egal was, und schließen Sie die Eingangs-und die Ausgangs-Ressource danach:hier ist meine Lösung für das Ressourcenmanagement in der Scala:
Habe ich dieses in mehrere Scala-apps, einschließlich der Verwaltung von Ressourcen in Spark-Vollzieher. und man sollte sich bewusst sein, dass wir andere noch bessere Möglichkeiten zum verwalten von Ressourcen-wie in CatsIO: https://typelevel.org/cats-effect/datatypes/resource.html. wenn Sie sind ok mit reinen FP-in-Scala.
zur Beantwortung Ihrer letzten Frage kann man definitiv nest der Ressource wie dieses:
diese Weise, nicht nur, dass diese Ressourcen geschützt werden, Auslaufen, werden Sie auch veröffentlicht in der richtigen Reihenfolge(wie stack). gleiche Verhalten wie die Ressource Monade aus CatsIO.