Wie kann man in Scala mehrere Ausnahmen gleichzeitig abfangen? Gibt es einen besseren Weg als in C #: Mehrere Ausnahmen gleichzeitig abfangen?
Wie kann man in Scala mehrere Ausnahmen gleichzeitig abfangen? Gibt es einen besseren Weg als in C #: Mehrere Ausnahmen gleichzeitig abfangen?
Antworten:
Sie können das gesamte Muster wie folgt an eine Variable binden:
try {
throw new java.io.IOException("no such file")
} catch {
// prints out "java.io.IOException: no such file"
case e @ (_ : RuntimeException | _ : java.io.IOException) => println(e)
}
Siehe die Scala-Sprachspezifikation auf Seite 118, Abschnitt 8.1.11, die als Musteralternativen bezeichnet wird.
Sehen Sie sich Pattern Matching Unleashed an, um einen tieferen Einblick in Pattern Matching in Scala zu erhalten.
Da Sie in der catch-Klausel Zugriff auf die vollständigen Mustervergleichsfunktionen von scala haben, können Sie viel tun:
try {
throw new IOException("no such file")
} catch {
case _ : SQLException | _ : IOException => println("Resource failure")
case e => println("Other failure");
}
Beachten Sie, dass Sie, wenn Sie immer wieder dieselben Handler schreiben müssen, eine eigene Steuerungsstruktur dafür erstellen können:
def onFilesAndDb(code: => Unit) {
try {
code
} catch {
your handling code
}
}
Einige dieser Methoden sind im Objekt scala.util.control.Exceptions verfügbar . Failing, FailAsValue, Handling kann genau das sein, was Sie brauchen
Bearbeiten: Im Gegensatz zu den folgenden Ausführungen können alternative Muster gebunden werden, sodass die vorgeschlagene Lösung unnötig komplex ist. Siehe @ agilesteel-Lösung
Leider haben Sie mit dieser Lösung keinen Zugriff auf die Ausnahme, in der Sie die alternativen Muster verwenden. Meines Wissens können Sie kein alternatives Muster mit case binden e @ (_ : SqlException | _ : IOException)
. Wenn Sie also Zugriff auf die Ausnahme benötigen, müssen Sie Matcher verschachteln:
try {
throw new RuntimeException("be careful")
} catch {
case e : RuntimeException => e match {
case _ : NullPointerException | _ : IllegalArgumentException =>
println("Basic exception " + e)
case a: IndexOutOfBoundsException =>
println("Arrray access " + a)
case _ => println("Less common exception " + e)
}
case _ => println("Not a runtime exception")
}
Sie können auch verwenden scala.util.control.Exception
:
import scala.util.control.Exception._
import java.io.IOException
handling(classOf[RuntimeException], classOf[IOException]) by println apply {
throw new IOException("foo")
}
Dieses spezielle Beispiel ist möglicherweise nicht das beste Beispiel, um zu veranschaulichen, wie Sie es verwenden können, aber ich finde es in vielen Fällen ziemlich nützlich.
Dies war der einzige Weg für mich, der durch die ging, sbt clean coverage test coverageReport
ohne die böse Parsing-Ausnahme zu werfen ...
try {
throw new CustomValidationException1(
CustomErrorCodeEnum.STUDIP_FAIL,
"could be throw new CustomValidationException2")
} catch {
case e
if (e.isInstanceOf[CustomValidationException1] || e
.isInstanceOf[CustomValidationException2]) => {
// run a common handling for the both custom exceptions
println(e.getMessage)
println(e.errorCode.toString) // an example of common behaviour
}
case e: Exception => {
println("Unknown error occurred while reading files!!!")
println(e.getMessage)
// obs not errorCode available ...
}
}
// ...
class CustomValidationException1(val errorCode: CustomErrorCodeEnum, val message: String)
class CustomValidationException2(val errorCode: CustomErrorCodeEnum, val message: String)
sbt clean coverage test coverageReport
zum Zeitpunkt des Schreibens nicht durchgeht