Scala高阶函数

问题描述 投票:0回答:1

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

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

可能吗?请帮忙

UPD:

我试着这样做我的课:

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

scala user-defined-functions implicit
1个回答
1
投票

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

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

或者你可以使用currying

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

© www.soinside.com 2019 - 2024. All rights reserved.