9

ファイルに次のダミーの Scala コードがありますtest.scala

class Transaction {
  def begin() {}
  def commit() {}
  def rollback() {}
}

object Test extends Application {
  def doSomething() {}

  val t = new Transaction()
  t.begin()
  try {
    doSomething()
    t.commit()
  } catch {
    case _ => t.rollback()
  }
}

これを Scala 2.8 RC1 でコンパイルするとscalac -Xstrict-warnings test.scala、次の警告が表示されます。

test.scala:16: warning: catch clause swallows everything: not advised.
    case _ => t.rollback()
    ^
one warning found

では、キャッチオール式が推奨されない場合、代わりにそのようなパターンを実装するにはどうすればよいでしょうか? それとは別に、なぜそのような表現がとにかくアドバイスされないのですか?

4

4 に答える 4

9

おそらくすべてをキャッチしたくないので、警告が存在します。たとえば、何かを取り込もうとすることは一般的にはお勧めできませんjava.lang.Error。(別の例外で catch ブロックから追い出される可能性は十分にあります。)

また、すべてを有効にキャッチすることはできないため、これはアトミック/フェイルセーフ トランザクションを実装する安全な方法ではありません。あなたは次のようなもので良いです

try {
  t.commit()
} finally {
  if (!t.checkCommitted()) {
    t.rollback()
    if (!t.checkRolledback()) throw new FUBARed(t)
  }
}

新しいものを読み込むときに追加のテストを行って、tそれが適切な状態であることを確認します。

于 2010-04-28T06:25:19.380 に答える
2

これをテストするためのコンパイラはありませんが、トランザクションをロールバックした後に例外を再スローするべきではありませんか?つまり、これは

val t = new Transaction()
t.begin()
try {
  doSomething()
  t.commit()
} catch {
  case e => t.rollback(); throw e
}

すべての例外をキャッチしている場合は、のドキュメントにControlThrowable注意する必要があります。おそらく、トランザクションが異常終了時にロールバックすることを望んでいますが、非ローカルリターンまたは。のためにトランザクションをロールバックすることは望まないでしょうutil.control.Breaks.break。もしそうなら、あなたは次のようなことをしたいかもしれません:

val t = new Transaction()
t.begin()
try {
  doSomething()
  t.commit()
} catch {
  case ce : ControlThrowable => throw ce // propagate
  case e => t.rollback(); throw e        // roll-back and propagate
}
于 2010-04-28T06:17:53.917 に答える
1

まず、これはエラーではなく警告であることに注意してください。それでも、-Xstrict-warings オプションでのみ警告が発生します。言い換えれば、論理的な間違いをしている可能性がありますが、それはあなた次第です。

他の人が気づいたように、ほとんどの場合、すべての例外をキャッチすることは意味がなく、次のようにする必要があります。

t.begin()
try {
  doSomething()
  t.commit()
} catch {
  case e: DuplicatedKeyError => ...
  case e: BrokenConnectionError => ...
  case e: DumbInputDetectedError => ...
}

つまり、すべての既知のエラー タイプを有意義に処理します。

ただし、考えられるすべての例外を無視する (または同じ方法で処理する) ことに自信がある場合は、警告を無視してください。

于 2010-04-28T13:45:40.973 に答える