在 try 块中保留最少的代码
Leaving minimal code inside try block
考虑这样定义的函数 f
:
def f() = {
try { g(h()) }
catch { case _: E => j() }
}
函数 g
、h
和 j
实际上可以是任何 code/expression.
考虑到只有h
可能会抛出E
类型的异常,如何重写f
使得在h
中只剩下h
try
块?
如果 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()
}
}
您可以改用 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
),但这应该是大致相当于你的例子。
Try { h() } match {
case Sucess(x) => g(x)
case _ => j()
}
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
考虑这样定义的函数 f
:
def f() = {
try { g(h()) }
catch { case _: E => j() }
}
函数 g
、h
和 j
实际上可以是任何 code/expression.
考虑到只有h
可能会抛出E
类型的异常,如何重写f
使得在h
中只剩下h
try
块?
如果 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()
}
}
您可以改用 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
),但这应该是大致相当于你的例子。
Try { h() } match {
case Sucess(x) => g(x)
case _ => j()
}
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