Scala 高阶函数

热点

我想让函数作为类构造的参数。我有一些我想在课堂上计算的函数(某种惰性计算)

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 和连接的 PreparedStatement 的 ResultSet

传说

你能行的。它看起来像这样

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)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章