6

可変変数を避けようとしていますが、問題は、try内で初期化する必要があるvalにアクセスする必要があることです(これは、移行が失敗するdb操作です)。finallyブロックにそのvarが必要です。

私はいくつかの選択肢を試しました:

tryブロック内でvalを宣言する

try {
  val resultSet = SQL(sql).resultSet
  return ColumnInfo(resultSet.getMetaData)
} catch {
  case e => throw new ColumnInfoException("Error getting metadata")
} finally {
  resultSet.close
}

error: not found: value resultSet

初期化せずにtryブロックの外側でvalを宣言する

val resultSet: java.sql.ResultSet
try {
  resultSet = SQL(sql).resultSet
  return ColumnInfo(resultSet.getMetaData)
} catch {
  case e => throw new ColumnInfoException("Error getting metadata")
} finally {
  resultSet.close
}

error: only classes can have declared but undefined members

動作するように見える変数を使用する

var resultSet: java.sql.ResultSet = null
try {
  resultSet = SQL(sql).resultSet
  return ColumnInfo(resultSet.getMetaData)
} catch {
  case e => throw new ColumnInfoException("Error getting metadata")
} finally {
  resultSet.close
}

そして最後に、かなり汚れているように見えるtry-catchブロックをネストします

try {
  val resultSet = SQL(sql).resultSet
  try {
    return ColumnInfo(resultSet.getMetaData)
  } catch {
    case e => throw new ColumnInfoException("Error getting metadata")
  } finally {
    resultSet.close
  }
} catch {
  case e => throw new ColumnInfoException("Error opening resultSet")
}

varsの使用やtry-catchブロックのネストを回避するためのより良いアプローチはありますか?

4

4 に答える 4

3
import scala.util.control.Exception._

allCatch.either(SQL(sql).resultSet).right.flatMap{ resultSet =>
  val ans = allCatch.either(ColumnInfo(resultSet.getMetaData))
  resultSet.close
  ans
}.fold(e => throw e, identity)

または、をスキップして、foldにパッケージ化された例外を保持することもできますLeft

于 2012-09-11T06:08:42.477 に答える
2

from this question Functional try & catch w/ Scala

ローンのパターンについて学びました: https://wiki.scala-lang.org/display/SYGN/Loan

Play フレームワーク自体は DB.withConnection メソッドで使用しているようです

于 2012-09-11T05:17:16.930 に答える
2

Scala では、tryブロックはです。あなたの場合、両方を含むタプルに評価できますval

val res: (java.sql.ResultSet, ColumnInfo) = try {
  val rs = SQL(sql).resultSet
  (rs, ColumnInfo(rs.getMetaData))
} catch {
  case _: Throwable => throw new Exception("Error getting metadata")
} finally {
  res._1.close
}
val columnInfo = res._2
于 2014-10-08T10:05:16.607 に答える
0

最初の catch ブロックを取り除きます。

try {
  val resultSet = SQL(sql).resultSet
  try {
    ColumnInfo(resultSet.getMetaData)
  } finally {
    resultSet.close
  }
} catch {
  case e => throw new ColumnInfoException("Error opening resultSet")
}
于 2012-09-11T05:17:43.230 に答える