优化Scala中Try.recover的使用,寻求简洁解包实现方案
Scala中Try解包的简洁实现方案探讨
在Scala里,常见的Try解包写法如下:
Try { input.charAt(100) // 易出错的计算逻辑 } match { case Success(c) => c // 仅解包值 case Failure(e) => println(e) // 记录异常 '?' // 提供默认值 }
这段代码功能没问题,但case Success(c) => c属于冗余的恒等转换,我们更希望把记录异常+返回默认值的错误处理逻辑作为核心凸显出来。
已尝试的替代方案
使用
recover方法:Try { input.charAt(100) // 易出错的计算逻辑 } recover { e => println(e) // 记录异常 '?' // 提供默认值 } get缺点:
recover返回Try[T](此时必然是Success),需要调用get解包,还需启用postFixOps语法。使用
getOrElse方法:Try { "input".charAt(100) // 易出错的计算逻辑 } getOrElse { // println(e) // 无法获取异常,无法记录日志 'a' // 提供默认值 }缺点:无法访问异常实例,无法实现日志记录需求。
理想的方法定义
我们需要一个类似unwrap的方法,定义如下:
def unwrap[U >: T](pf: PartialFunction[Throwable, U]): U
它能直接从Success中解包出T,或从Failure中取出Throwable并通过偏函数转换为U。
简洁实现方案
给Try添加扩展方法是最直接且简洁的方案,并非小题大做:
implicit class TryOps[T](private val t: Try[T]) extends AnyVal { def unwrap[U >: T](pf: PartialFunction[Throwable, U]): U = t.recover(pf).get }
使用方式非常直观,完全符合需求:
Try { input.charAt(100) } unwrap { e => println(e) '?' }
补充说明
近5年Scala标准库并未新增原生方法实现该逻辑,因此上述扩展方法是当前最优的简洁方案——既消除了冗余的模式匹配代码,又完整保留了异常处理与默认值返回的核心逻辑,同时让代码结构更聚焦。
内容的提问来源于stack exchange,提问作者Brad Carter
相关产品推荐
相关产品推荐

