scala 的 Try 优雅的错误行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21556310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
scala's Try elegant on error behavior
提问by Pablo Fernandez
Is there a more elegant way of doing this in scala?
在 Scala 中是否有更优雅的方式来做到这一点?
def doTheDangerousThing(): Try[Result] = {
val result = Try(dangerousOp)
if (result.isFailure) {
println("error")
}
result
}
回答by vptheron
I think your if statement is perfectly valid. Here is another alternative:
我认为你的 if 语句是完全有效的。这是另一种选择:
def doTheDangerousThing(): Try[Result] = Try(dangerousOp) recoverWith {
case exception => println("error"); Failure(exception)
}
回答by Alex
Not sure if this is more idiomatic, but sometimes I find that placing the recoverWithin this manner improves readability for me:
不确定这是否更惯用,但有时我发现recoverWith以这种方式放置可以提高我的可读性:
def doDangerousThing(): Try[Result] = Try {
dangerousOp
} recoverWith {
case t: Throwable => println("error"); Failure(t)
}
回答by Sane
Something like this:
像这样的东西:
def doTheDangerousThing[Result](dangerousOp: =>Result): Try[Result] = Try(dangerousOp) match {
case o @ Failure(_) => println("error"); o
case _ => _
}
回答by elm
My preferred,
我的首选,
def doTheDangerousThing(): Option[Result] = Try (dangerousOp) toOption
If the Tryis successful you will get a Some(value), if it fails a None.
如果Try成功,您将获得一个Some(value),如果失败则获得一个None。
For a large compilation on Tryuses, have a look at Try introduced in Scala 2.10.0.
有关使用的大型编译Try,请查看Scala 2.10.0 中引入的 Try。
回答by Daniel C. Sobral
There are ways. For instance:
有办法。例如:
def doTheDangerousThing(): Try[Result] = {
val result = Try(dangerousOp)
result.failed foreach { _ =>
println("error")
}
result
}
Or, if you don't want to repeat resultall through, then:
或者,如果您不想一直重复result,则:
def doTheDangerousThing(): Try[Result] = {
Try(dangerousOp) recover {
case ex => println("error"); throw ex
}
}
回答by Johnny
In some cases I love to use two-step approach which will allow me a more granular error message control:
在某些情况下,我喜欢使用两步法,这将允许我进行更细粒度的错误消息控制:
def retrieveData(dataId: String): Try[String] = {
Try {
Option(someApi(dataId))
.getOrElse(throw SomeApiFailedException("invalid dataId"))
} recoverWith {
case e: SomeApiFailedException => Failure(e)
case e: Throwable => Failure(SomeApiFailedException("failed retrieve dataId"))
}
}
case class SomeApiFailedException(err: String) extends RuntimeException(err)
回答by tuxdna
I could choose from either of the three implementations, depending on whether I want to:
我可以从三个实现中的任何一个中进行选择,具体取决于我是否想要:
- Simply propagate it upwards (
doTheDangerousThing1) - Ignore the error (
doTheDangerousThing2) - Intercept the error while propagating it upwards (
doTheDangerousThing3)
- 只需向上传播 (
doTheDangerousThing1) - 忽略错误 (
doTheDangerousThing2) - 向上传播时截获误差 (
doTheDangerousThing3)
Here is the code:
这是代码:
import scala.util.{Try,Success,Failure}
object temp {
type Result = Int
def dangerousOp = {
val r = scala.util.Random.nextInt(10)
if (r > 5) r else throw new RuntimeException("Failed on " + r)
}
def logMessage[T](t: T) = println(t)
def doTheDangerousThing1(): Try[Result] = Try(dangerousOp)
def doTheDangerousThing2(): Option[Result] = {
Try(dangerousOp) match {
case Success(r) => Option(r)
case _ => None
}
}
def doTheDangerousThing3(): Try[Result] = {
Try(dangerousOp) match {
case t @ Success(r) => t
case t @ _ => logMessage("failed: "+t); t
}
}
}
Inside the REPL
REPL 内部
scala> doTheDangerousThing1
res0: scala.util.Try[Result] = Success(9)
scala> doTheDangerousThing1
res1: scala.util.Try[Result] = Success(9)
scala> doTheDangerousThing2
res2: Option[Result] = None
scala> doTheDangerousThing2
res3: Option[Result] = Some(7)
scala> doTheDangerousThing3
failed: Failure(java.lang.RuntimeException: Failed on 0)
res4: scala.util.Try[Result] = Failure(java.lang.RuntimeException: Failed on 0)
scala> doTheDangerousThing3
failed: Failure(java.lang.RuntimeException: Failed on 0)
res5: scala.util.Try[Result] = Failure(java.lang.RuntimeException: Failed on 0)
回答by James Adam
Well, I suppose you could do something like this:
好吧,我想你可以这样做:
def doTheDangerousThing(): Option[Result] =
Try(dangerousOp) match {
case Success(result) => Some(result)
case Failure(e) => None //might want to log the error as well
}

