java-try-mit-Ressourcen-nicht die Arbeit mit scala
In der Scala-Anwendung, versuche zu Lesen von Zeilen aus einer Datei, die mit java nio try-with-resource-Konstrukt.
Scala-version 2.11.8
Java version 1.8
try(Stream<String> stream = Files.lines(Paths.get("somefile.txt"))){
stream.forEach(System.out::println); //will do business process here
}catch (IOException e) {
e.printStackTrace(); //will handle failure case here
}
Aber der compiler wirft Fehler wie
◾nicht gefunden: value-stream
◾Ein try ohne catch-oder finally-ist äquivalent zu setzen, seinen Körper in einen block; es sind keine Ausnahmen behandelt.
Nicht sicher, was das problem ist. Bin neu mit Java NIO, so dass jede Hilfe wird sehr geschätzt.
- Es ist nichts falsch im java-code
- Ist dieser anwendbar?
- Scala und Java sind unterschiedliche Sprachen. Sie können nicht nur erwarten, dass Java-syntax kompiliert schön, in einem Scala-Programm. Verwandte: stackoverflow.com/questions/25634455/..., stackoverflow.com/questions/2207425/...
- Natürlich ist der Scala-compiler wirft Fehler. Das ist nicht Scala-code.
- verstanden. Tut-scala haben try-mit-Ressourcen, die äquivalente Konstrukt?
- Nizet, danke für den Hinweis
- Scala hat die
try
/catch
konstruieren, wie Java. Es hat auch die Versuchen Monade. (Nicht wirklich eine echte Monade, aber ziemlich nah dran.) - Hier ist eine weitere Antwort auf dieses problem, die alle Adressen der verschiedenen Signalwege für beide
java.lang.AutoCloseable
und fürscala.io.Source
: stackoverflow.com/a/34277491/501113
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Ihr auf der Scala 2.13 dann sollten Sie das Mit dem Objekt.
In älteren Versionen von scala, es gibt keinen direkt-support für javas try-with-resources-Konstrukt, aber er kann ziemlich leicht bauen Sie Ihren eigenen support, indem die Darlehen Muster. Das folgende ist eine einfache, aber nicht optimale Beispiel, das ist leicht zu verstehen. Eine weitere richtige Lösung gegeben wird später in dieser Antwort:
Diese definiert eine wiederverwendbare Methode, das funktioniert so ähnlich wie ein try-with-resource-Konstrukt in java. Es funktioniert, indem es zwei parameter. Zunächst ist nimmt die eine Unterklasse von Autoclosable Instanz, und zweiten dauert es eine Funktion, die den gleichen Autoclosable Typ als paremeter. Der Rückgabetyp der Funktion parameter wird als Rückgabetyp der Methode. Die Methode führt dann die Funktion innerhalb eines try -, und schließen Sie die autocloseble in seiner finally-block.
Können Sie es wie folgt (wird hier verwendet, um das Ergebnis findAny() auf den stream.
Bei Ihrem tun zu wollen, exceptions fangen, haben Sie 2 Möglichkeiten.
Fügen Sie einen try/catch-block rund um den Strom.findAny () - Aufruf.
Oder fügen Sie einen catch-block der try-block in der autoClose-Methode. Beachten Sie, dass dies sollte nur durchgeführt werden, wenn die Logik innerhalb der catch-block ist nutzbar von allen Orten, wo autoClose genannt wird.
Beachten Sie, dass als Vitalii witrenko darauf hin, diese Methode wird schlucken Sie die exception aus der close-Methode auf, wenn die Funktion durch den Kunden geliefert, und die close-Methode auf das AutoCloseable eine exception wirft. Javas try-mit-Ressourcen behandelt, und wir können machen autoClose tun dies, indem Sie ein bisschen komplexer:
Dies funktioniert, indem Sie die Speicherung der potenziell Ausnahme der client-Funktion wirft, und die addition der möglichen Ausnahme der close-Methode als unterdrückte exception. Das ist ziemlich nah an, wie oracle erklärt, dass try-mit-Ressourcen ist es tatsächlich zu tun: http://www.oracle.com/technetwork/articles/java/trywithresources-401775.html
Dies ist jedoch Scala, und viele Menschen werden es vorziehen, das Programm in ein mehr funktionale Weise. In ein mehr funktionale Art und Weise, die Methode zurückgeben soll, einen Versuch, statt eine Ausnahme zu werfen. Dies vermeidet eine Nebenwirkung, eine Ausnahme zu werfen, und macht klar, dass der client, dass die Antwort kann ein Fehler sein, die behandelt werden muss (wie bereits in der Antwort von Stas). In einer praktischen Umsetzung, wir möchten auch, um zu vermeiden, dass ein var, also ein naiver Ansatz wäre:
Dies könnte Ihnen benannt werden:
Oder Sie könnten einfach anrufen .Holen Sie sich auf myTry zu machen, das Ergebnis zurückgibt, oder werfen eine Ausnahme.
Jedoch als Kolmar, betont in einem Kommentar, dieser Implementierung ist fehlerhaft, durch, wie die return-Anweisung kann in scala. Betrachten Sie das folgende:
Würden wir erwarten, dass diese zu drucken, Schließen!, aber wird es nicht. Das problem ist hier das explizite return-Anweisung innerhalb der Funktion Körper. Es macht die Methode überspringen Sie die Logik in der autoCloseTry Methode, und damit nur die Renditen Erfolg(0), ohne schließen der Ressource.
Um dieses problem zu beheben, erstellen wir ein mix aus den 2 Lösungen, eine, die die funktionale API der Rücksendung einen Versuch Wert, aber nutzt die klassische Implementierung, basierend auf try/finally-blocks:
Sollte dies das problem beheben, und kann genauso verwendet werden wie der erste Versuch. Aber es zeigt, dass diese ein bisschen fehleranfällig, und die fehlerhafte Umsetzung wurde in dieser Antwort als die empfohlene version für einige Zeit. So, es sei denn, Sie versuchen zu vermeiden, dass zu viele Bibliotheken, sollten Sie richtig betrachten mit dieser Funktion aus einer Bibliothek. Ich denke, dass es schon eine andere Antwort verweist auf ein, aber meine Vermutung ist, dass es mehrfach Bibliotheken, löst dieses problem auf unterschiedliche Weise.
fun(closeable)
undclose()
Ausnahmen. Die Letzte Ausnahme nur im hintergrund verstecken, die erste! Sie sollten wahrscheinlich in der Nähe einer Ressource in einem anderen try-Anweisung und verwenden SieaddSuppressed()
wie gezeigt, in den die AntwortTry
ist falsch.Try
nur FängeNonFatal
Ausnahmen, aber die Ressourcen müssen gereinigt werden, auch für schwere und Kontrollfluss Ausnahmen. Betrachten Sie diesen code:class MyClass extends AutoCloseable { override def close() = println("Closing!") }; def foo: Try[Int] = { autoCloseTry(new MyClass) { _ => return Success(0) } }
. Aufruffoo
nicht nennenclose
mitautoCloseTry
, aber funktioniert OK mitautoClose
.java.lang.AutoCloseable
und fürscala.io.Source
: stackoverflow.com/a/34277491/501113Alternativ können Sie Abgehackt ist TryClose Monade tun dies in einer for-comprehension in einem composeable auf ähnliche Weise wie in Scala Versuchen.
Hier ist, wie Sie es tun würde, mit Ihrer stream:
Weitere Infos hier:
https://github.com/choppythelumberjack/tryclose
Haben Sie bereits in einer der Antworten Ansatz:
Aber ich denke, das folgende ist viel eleganter:
Durch die Letzte IMHO ist es einfacher zu handhaben ist die Ablaufsteuerung.
resource.close()
eine Exception wirft? Diese Antwort hat: stackoverflow.com/a/34277491/501113