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

これはスカラ文法の問題です。括弧を追加して、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 に答える