Scala中对传入函数的Try结果做模式匹配及泛化实现
问题解决
一、实现对Try[String]的Success/Failure匹配
因为computeTry是基于回调的API,无法直接对其返回值做模式匹配,我们可以用Promise将回调式逻辑转换为Future,再通过Future获取结果并完成匹配:
import scala.concurrent.{Promise, Await} import scala.concurrent.duration._ import scala.util.{Try, Success, Failure} trait FunctionApi: def computeTry(funct: Try[String] => Unit): Unit = ??? def actUponTry(functionApi: FunctionApi): String = { // 创建Promise接收回调结果 val promise = Promise[String]() // 传入computeTry的回调,完成Promise状态 functionApi.computeTry { case Success(value) => promise.success(value) case Failure(ex) => promise.failure(ex) } // 阻塞获取Future结果(非阻塞场景可改用map/onComplete等异步处理) Await.result(promise.future, 5.seconds) match { case value => s"Success with $value" case Failure(ex) => s"Failure with exception ${ex.getMessage}" } }
测试示例修正(原调用示例存在语法错误,actUponTry直接返回String结果):
val success = Success("Some String") val succeeding = new FunctionApi: def computeTry(continuation: Try[String] => Unit): Unit = continuation(success) val wasSuccess = actUponTry(succeeding) // 输出: Success with Some String
二、泛化逻辑适配不同类型的Try回调
当新增computeTry2(funct: Try[Long] => Unit): Unit时,可通过泛型方法复用匹配逻辑,无需修改原有API结构:
1. 提取通用逻辑
先封装回调转Future的通用方法,再处理结果:
import scala.concurrent.{Promise, Future, Await} import scala.concurrent.duration._ import scala.util.{Try, Success, Failure} trait FunctionApi: def computeTry(funct: Try[String] => Unit): Unit = ??? def computeTry2(funct: Try[Long] => Unit): Unit = ??? // 通用:将回调式API转为Future private def callbackToFuture[T](handler: (Try[T] => Unit) => Unit): Future[T] = { val promise = Promise[T]() handler { case Success(v) => promise.success(v) case Failure(e) => promise.failure(e) } promise.future } // 泛化的结果处理方法 def actUponTryGeneric[T](handler: (Try[T] => Unit) => Unit): String = { val future = callbackToFuture(handler) Await.result(future, 5.seconds) match { case value => s"Success with $value" case Failure(ex) => s"Failure with exception ${ex.getMessage}" } } // 针对不同compute方法的调用入口 def actUponTryString(api: FunctionApi): String = actUponTryGeneric(api.computeTry) def actUponTryLong(api: FunctionApi): String = actUponTryGeneric(api.computeTry2)
2. 调用示例
val longSuccess = Success(123L) val longSucceeding = new FunctionApi: override def computeTry2(continuation: Try[Long] => Unit): Unit = continuation(longSuccess) val wasLongSuccess = actUponTryLong(longSucceeding) // 输出: Success with 123
三、异步非阻塞场景的适配
如果不需要阻塞获取结果,可改用Future异步操作链,避免线程阻塞:
def actUponTryAsync(api: FunctionApi): Future[String] = { val promise = Promise[String]() api.computeTry { case Success(v) => promise.success(v) case Failure(e) => promise.failure(e) } promise.future .map(v => s"Success with $v") .recover { case ex => s"Failure with exception ${ex.getMessage}" } }
内容的提问来源于stack exchange,提问作者codeaperature
相关产品推荐
相关产品推荐

