即使在Scala中捕获异常后仍执行代码块
在我当前的方法中,我尝试进行一系列调用,如果其中任何一个调用失败,我希望能够继续运行其余的调用,同时捕获抛出的异常。在Scala,我很难弄明白这一点 所以在这个例子中,我想启动这些调用中的每一个——RunA、RunB和RunC,但是如果RunB抛出一个异常,我想打印它,然后继续启动RunC即使在Scala中捕获异常后仍执行代码块,scala,exception-handling,Scala,Exception Handling,在我当前的方法中,我尝试进行一系列调用,如果其中任何一个调用失败,我希望能够继续运行其余的调用,同时捕获抛出的异常。在Scala,我很难弄明白这一点 所以在这个例子中,我想启动这些调用中的每一个——RunA、RunB和RunC,但是如果RunB抛出一个异常,我想打印它,然后继续启动RunC var result = Try { new RunA() new RunB() new RunC() } catch { case e: Throwable =>
var result = Try {
new RunA()
new RunB()
new RunC()
} catch {
case e: Throwable => e.printStackTrace()
false
}
除了将它们单独包装在一个Try/Catch中之外,我确信还有更好的方法来做到这一点,这就是为什么我希望有人能帮上忙的原因
我查看了“忽略”异常,但它似乎完全忽略了我至少要记录的异常
谢谢 您将scala.util.Try与Try{}catch{}混合使用,这是不同的概念。Try将函数包装到Successresult或Failureerror类中,Try-catch类似于Java Try-catch。我建议你这样做:
class RunA
class RunB
class RunC
class Result(a: RunA, b: RunB, c: RunC)
implicit class LogFailure[T](t: Try[T]) {
def logFailure: Try[T] = t match {
case scala.util.Failure(err) => err.printStackTrace(); t
case _ => t
}
}
val tryA= Try(new RunA())
val tryB= Try(new RunB())
val tryC = Try(new RunC())
val result: Try[Result] = for {
a <- tryA.logFailure
b <- tryB.logFailure
c <- tryC.logFailure
} yield {
// do smth with a, b, c
new Result(a, b, c)
}
import scala.reflect.ClassTag
import scala.util.{Try, Success, Failure}
def tryAndLog[T: ClassTag] = Try {
implicitly[ClassTag[T]].runtimeClass.newInstance.asInstanceOf[T] // new instance
} match {
case Success(_) => true
case Failure(ex) => ex.printStackTrace ; false
}
def tryRunAll = {
val A = tryAndLog[RunA]
val B = tryAndLog[RunB]
val C = tryAndLog[RunC]
A && B && C // returns true if all invocations succeeded, false otherwise
}
如果A、B、C成功,您将获得成功结果如果其中一个失败,您将获得第一个异常的失败,但是所有这些都将记录为打印堆栈跟踪您将scala.util.Try与Try{}catch{}混合使用,这是不同的概念。Try将函数包装到Successresult或Failureerror类中,Try-catch类似于Java Try-catch。我建议你这样做:
class RunA
class RunB
class RunC
class Result(a: RunA, b: RunB, c: RunC)
implicit class LogFailure[T](t: Try[T]) {
def logFailure: Try[T] = t match {
case scala.util.Failure(err) => err.printStackTrace(); t
case _ => t
}
}
val tryA= Try(new RunA())
val tryB= Try(new RunB())
val tryC = Try(new RunC())
val result: Try[Result] = for {
a <- tryA.logFailure
b <- tryB.logFailure
c <- tryC.logFailure
} yield {
// do smth with a, b, c
new Result(a, b, c)
}
import scala.reflect.ClassTag
import scala.util.{Try, Success, Failure}
def tryAndLog[T: ClassTag] = Try {
implicitly[ClassTag[T]].runtimeClass.newInstance.asInstanceOf[T] // new instance
} match {
case Success(_) => true
case Failure(ex) => ex.printStackTrace ; false
}
def tryRunAll = {
val A = tryAndLog[RunA]
val B = tryAndLog[RunB]
val C = tryAndLog[RunC]
A && B && C // returns true if all invocations succeeded, false otherwise
}
如果A、B、C将成功,您将获得成功结果如果其中一个失败,您将获得第一个异常的失败,但是所有这些都将被记录为打印堆栈跟踪首先,不要将try{…}catch{…}与scala.util混合使用。try{…}
你可以
import scala.util._
val runA = Try{ new RunA }
val runB = Try{ new RunB }
val runC = Try{ new RunC }
然后处理你认为合适的异常。例如,如果要打印并继续,可以在此处处理try语句:
def getOrPrint[A](f: => A): Option[A] = Try{ f } match {
case Success(x) => Some(x)
case Failure(e) => e.printStackTrace; None
}
getOrPrint{ new RunA }
...
首先,不要将try{…}catch{…}与scala.util.try{…}混在一起
你可以
import scala.util._
val runA = Try{ new RunA }
val runB = Try{ new RunB }
val runC = Try{ new RunC }
然后处理你认为合适的异常。例如,如果要打印并继续,可以在此处处理try语句:
def getOrPrint[A](f: => A): Option[A] = Try{ f } match {
case Success(x) => Some(x)
case Failure(e) => e.printStackTrace; None
}
getOrPrint{ new RunA }
...
使用scalaz可以有更优雅的方式来完成这类事情,例如,在这里阅读一篇文章,获得一些灵感:,但只有使用Scala,您可以执行以下操作:
class RunA
class RunB
class RunC
class Result(a: RunA, b: RunB, c: RunC)
implicit class LogFailure[T](t: Try[T]) {
def logFailure: Try[T] = t match {
case scala.util.Failure(err) => err.printStackTrace(); t
case _ => t
}
}
val tryA= Try(new RunA())
val tryB= Try(new RunB())
val tryC = Try(new RunC())
val result: Try[Result] = for {
a <- tryA.logFailure
b <- tryB.logFailure
c <- tryC.logFailure
} yield {
// do smth with a, b, c
new Result(a, b, c)
}
import scala.reflect.ClassTag
import scala.util.{Try, Success, Failure}
def tryAndLog[T: ClassTag] = Try {
implicitly[ClassTag[T]].runtimeClass.newInstance.asInstanceOf[T] // new instance
} match {
case Success(_) => true
case Failure(ex) => ex.printStackTrace ; false
}
def tryRunAll = {
val A = tryAndLog[RunA]
val B = tryAndLog[RunB]
val C = tryAndLog[RunC]
A && B && C // returns true if all invocations succeeded, false otherwise
}
使用scalaz可以有更优雅的方式来完成这类事情,例如,在这里阅读一篇文章,获得一些灵感:,但只有使用Scala,您可以执行以下操作:
class RunA
class RunB
class RunC
class Result(a: RunA, b: RunB, c: RunC)
implicit class LogFailure[T](t: Try[T]) {
def logFailure: Try[T] = t match {
case scala.util.Failure(err) => err.printStackTrace(); t
case _ => t
}
}
val tryA= Try(new RunA())
val tryB= Try(new RunB())
val tryC = Try(new RunC())
val result: Try[Result] = for {
a <- tryA.logFailure
b <- tryB.logFailure
c <- tryC.logFailure
} yield {
// do smth with a, b, c
new Result(a, b, c)
}
import scala.reflect.ClassTag
import scala.util.{Try, Success, Failure}
def tryAndLog[T: ClassTag] = Try {
implicitly[ClassTag[T]].runtimeClass.newInstance.asInstanceOf[T] // new instance
} match {
case Success(_) => true
case Failure(ex) => ex.printStackTrace ; false
}
def tryRunAll = {
val A = tryAndLog[RunA]
val B = tryAndLog[RunB]
val C = tryAndLog[RunC]
A && B && C // returns true if all invocations succeeded, false otherwise
}
太好了,这正是我想要的。现在唯一的问题是我必须修改getOrPrint以返回一个布尔值,然后我必须按照其他人的建议&&来聚合我的结果。不幸的是,这在我的解决方案中导致了一个纠结,当我测试失败时,它返回一个false,我必须将None更改为false,然后它停止执行。有很多方法可以解决这个问题,所以我会尝试单独解决。很好,这正是我想要的。现在唯一的问题是我必须修改getOrPrint以返回一个布尔值,然后我必须按照其他人的建议&&来聚合我的结果。不幸的是,这在我的解决方案中导致了一个纠结,当我测试失败时,它返回一个false,我必须将None更改为false,然后它停止执行。有很多方法可以解决这个问题,所以我将尝试单独解决。