考虑以这种方式定义的函数f
:
def f() = {
try { g(h()) }
catch { case _: E => j() }
}
函数g
,h
和j
实际上可以是任何代码/表达式。
考虑到只有h
可能会抛出E
类型的异常,如何重写f
,以便只有h
留在try
内阻止?
答案 0 :(得分:3)
Try { h() } match {
case Sucess(x) => g(x)
case _ => j()
}
答案 1 :(得分:2)
您可以使用scala.util.Try
代替。我在ideone中测试的简单程序:
import scala.util.Try
object Main extends App {
def f() = {
Try(h()).map(g).recover { case _: Exception => j() }.get
}
def g(x: Any) = "g:" + x
def h(): Any = throw new RuntimeException
def j() = "caught"
println(f()) // should print "g:caught"
}
老实说,我不会编写以.get
结尾的代码(相反,我会在整个代码库中传播Try
,如果我正在编写可以抛出异常的代码),但这应该大致相当于举个例子。
答案 2 :(得分:1)
def f() = Try(h()).map(g).getOrElse(j())
map
超过您的Try
结果。 g()
仅在Success()
上调用。使用getOrElse()
在Failure()
上提供默认值。
import scala.util.Try
def h() = if (util.Random.nextBoolean) 7 else throw new Error
def g(x:Int) = x*5
def j() = 11
Try(h()).map(g).getOrElse(j()) // returns 35 or 11
答案 3 :(得分:0)
如果Scala try
块可能有else
块 - 就像Python一样 - 可以用这样的方式编写f
的清晰定义:
def f() =
try { h() }
catch { case _: E => j() }
else { v => g(v) } // v is the resulting value from the try block
不幸的是,Scala不支持这样的事情。
这可能是一个 - 也许不那么干净 - 可能的解决方案:
def f() = {
val u =
try { Some(h()) }
catch { case _: E => None }
u match {
case Some(v) => g(v)
case None => j()
}
}