如何在Scala中包装传递函数的返回类型

时间:2017-08-07 12:42:04

标签: scala function

有没有办法只包装传递函数的返回类型?

我正在尝试使用try-with-resources scala equivalent中的干净地自动管理资源。我想做的是拥有嵌套的托管资源,即执行以下操作:

cleanly(db.connect())(_.close()) { connection =>
            cleanly(connection.prepareCall("{call procedure}"))(_.close()) { statement => 
                statement.setInt("batch", 1)
                statement.execute()
            }
        }  

然而,返回尝试[尝试[B]]。所以我稍微修改了cleanly函数的签名和实现:

def cleanly[A, B](resource: A)(cleanup: A => Unit)(doWork: A => Try[B]): Try[B] = {
        try {
            doWork(resource)
        }
        finally {
            try {
                if (resource != null) {
                    cleanup(resource)
                }
            } catch {
                case e: Exception => log.error("Error cleaning up resource.", e) // should be logged
            }
        }
    }

我试图通过新添加的方法 tryCleanly 来调用它,它将包装传递的函数以返回Try对象:

def tryCleanly[A, B](resource: A)(cleanup: A => Unit)(doWork: A => B): Try[B] = {
   cleanly[A,B](resource)(cleanup)(Try(doWork))
}

然而,尝试(doWork)的结果是

Try[(A) => B]

而不是

(A) => Try[B]

是否可以仅包装函数的结果类型?

2 个答案:

答案 0 :(得分:1)

def tryCleanly[A, B](resource: A)(cleanup: A => Unit)(doWork: A => B): Try[B] = {
   cleanly[A,B](resource)(cleanup)(a: A => Try(doWork(a)))
}

答案 1 :(得分:0)

@JoeK激励我再一次搞砸参数,所以归功于他。我最终得到的是:

def cleanly[A, B](resource: A)(cleanup: A => Unit)(doWork: A => Try[B]): Try[B] = {
    try {
        doWork(resource)
    }
    finally {
        try {
            if (resource != null) {
                cleanup(resource)
            }
        } catch {
            case e: Exception => log.error("Error cleaning up resource.", e) // should be logged
        }
    }
}

def tryCleanly[A, B](resource: A)(cleanup: A => Unit)(doWork: A => B): Try[B] = {
    cleanly[A,B](resource)(cleanup)(resource => Try(doWork(resource)))
}