2

Try/catch 可以像表达式一样使用,所以:

 scala> try { 3 } catch {case _ => 0}
 res52: Int = 3

还:

scala> try { 3 } catch {case _ => 0} finally try {println("side effect")} catch { case _ => println("catching side effect") } 
side effect
res50: Int = 3

那为什么不呢:

 scala> try { 3 } catch {case _ => 0} + 4
 <console>:1: error: ';' expected but identifier found.
   try { 3 } catch {case _ => 0} + 4

或者为什么不:

scala> try { 3 } catch {case _ => 0} match {case 3 => "hi"}
<console>:1: error: ';' expected but 'match' found.
   try { 3 } catch {case _ => 0} match {case 3 => "hi"}

我的目标是这样的函数定义:

def transact[T](code : Unit => T):T = 
   try {startTransaction; Right(code)} 
     catch {case t:Throwable => Left(t)} 
   finally try {endTransaction} 
     catch { case e:... if ... => throw e}  
 match  {
   case Right(e) => e
   case Left....
 }

当然,我可以将 try/catch 存储在 val 中并匹配 val:

 def transact[T](code : Unit => T):T = 
 {
   val transa = try {startTransaction; Right(code)} 
     catch {case t:Throwable => Left(t)} 
   finally try {endTransaction} 
     catch { case e:... if ... => throw e}  
transa match { 
 case ...
}
}

但它不再是一个单一的表达式,我需要在另一个 {} 中包装 - 如果我错了,请纠正我 - 意味着另一层函数对象包装也就是间接,在性能关键的地方。

那么,有没有办法将 try 用作完整表达式并避免这种间接性?

谢谢

4

1 回答 1

7

这是一个 scala 语法问题——只需添加括号将 try/catch 块转换为 SimpleExpr,这样您就可以继续对其进行操作:

scala> (try { 3 } catch {case _ => 0}) + 4
res1: Int = 7

scala> (try { 3 } catch {case _ => 0}) match {case 3 => "hi"}
res2: java.lang.String = hi

像往常一样,大括号和圆括号(大部分)是可以互换的——你的目标代码使用大括号会更好看(imo)。

不知道间接 - 你需要查看编译的字节码 - 但我怀疑它会有所作为。

有关语法问题的完整解释(这并不是我最初认为的运算符优先级问题),请参阅:https ://stackoverflow.com/a/7530565/178551

于 2012-11-11T13:40:43.993 回答