斯卡拉高阶函数



我想使函数作为类构造的参数。 我有一些函数想在类中计算(某种惰性计算(

class Foo(calc: PGSimpleDataSource => Connection => PreparedStatement => ResultSet => Option[A] ??? ) {
here some logic like:
def runCalc = calc ( resultSet ( preparedStatement ( connection )
resultSet.close()
preparedStatement.close()
connection.close()
send result somewhere ...
}

准备一些函数

implicit val dataSource: PGSimpleDataSource = Service.ds
implicit def getConnection(implicit ds: PGSimpleDataSource): Connection = ds.getConnection
implicit def getPreparedStatement(userId: UUID)(implicit con: Connection): PreparedStatement ={
val st = con.prepareStatement("SELECT * FROM bar WHERE id = CAST(? as UUID)")
st.setString(1, id.toString)
st
}
implicit def getResultSet(implicit ps: PreparedStatement): ResultSet = ps.executeQuery()
implicit def mapping(implicit rs: ResultSet): Option[Bar] = {
Iterator.continually(rs.next)
.takeWhile(identity)
.map(_ => Bar(UUID.fromString(rs.getString(1)))).toList.headOption
}

然后是一些功能,例如:

def getInstance(id: UUID) = new Foo(???)
val foo = getInstance(id)
foo.runCalc()

可能吗?请帮忙

更新:

我试着像这样上课:

class Foo[A](
con: => Connection,
ps: => PreparedStatement,
rs: => ResultSet,
mapping: => Option[A],
calc: Connection => PreparedStatement => ResultSet => Option[A]
) {
def run(): Unit = {
val result: Option[A] = calc(con)(ps)(rs)(mapping)
rs.close()
ps.close()
con.close()
}
}

但是我不明白下面怎么写"f"函数

它需要做映射( getResultSet ( getPreparedStatement (id, getConnection((

换句话说,映射需要需要 Id 和连接的 Prepared语句的结果集

你可以做到。它看起来像这样

case class Foo(calc: String => String => String => Option[String]) {
def run = {
val p1 = "p1"
val p2 = "p2"
val p3 = "p3"
calc(p1)(p2)(p3)
}
}

使用示例

object App extends App {
val f = (x: String) => (y: String) => (z: String) => {
Option(x + y + z)
}
val foo = Foo(f)
println(foo.run)
}

或者你可以使用咖喱

object App extends App {
val f = (x: String, y: String, z: String) => {
Option(x + y + z)
}
val foo = Foo(f.curried)
println(foo.run)
}

编辑

对于您的扩展问题,我可以提出这个类:

case class Foo[A](
getConnection: () => Connection,
getStatement: Connection => PreparedStatement,
getResultSet: PreparedStatement => ResultSet,
mapping: ResultSet => Option[A]) {
def run(): Option[A] = {
val connection = getConnection()
try{
val statement = getStatement(connection)
try{
val resultSet = getResultSet(statement)
try{
mapping(resultSet)
}finally {
resultSet.close()
}
}finally{
statement.close()
} 
} finally {
connection.close()
}
}
}

使用示例:

val foo = Foo(
() => new Connection(),
connection => new PreparedStatement(),
statement => new ResultSet(),
resultSet => Option("")
)

所有这些函数都具有上一步中的参数,因此例如,当您创建ResultSet时,您可以使用statement(但不能使用connection(。

相关内容

  • 没有找到相关文章

最新更新