我正在尝试避免mutables变量,但问题是我必须访问我需要在try内部初始化的val(这是一个迁移失败的db操作),我需要在finally块中使用var < / p>
我尝试了几种方法:
在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,这似乎有用
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")
}
我可以采取一些更好的方法来避免使用变量和嵌套try-catch块吗?
答案 0 :(得分: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
中。
答案 1 :(得分:2)
来自这个问题functional try & catch w/ Scala
我了解了贷款模式:https://wiki.scala-lang.org/display/SYGN/Loan
Play框架本身似乎与DB.withConnection方法一起使用
答案 2 :(得分:1)
在Scala中,try
阻止为an expression。在您的情况下,它可以评估为包含val
s:
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
答案 3 :(得分:0)
摆脱第一个障碍:
try {
val resultSet = SQL(sql).resultSet
try {
ColumnInfo(resultSet.getMetaData)
} finally {
resultSet.close
}
} catch {
case e => throw new ColumnInfoException("Error opening resultSet")
}