为何Scala的Try模式匹配会将Throwable判定为Success分支场景?
问题根因解析
Scala 2.11.12中Try.apply的底层实现逻辑等价于如下代码:
def apply[T](r: => T): Try[T] = try Success(r) catch { case NonFatal(e) => Failure(e) }
这个实现的判定规则非常明确:
- 只有当代码块
r的求值过程中,抛出了属于NonFatal范围的异常时,才会将异常封装为Failure实例返回 - 只要
r的求值流程正常结束,无论求值的返回值是什么类型,都会被封装为Success实例返回,不会因为返回值本身是Throwable类型就判定为执行失败
对应代码的实际执行流程
你编写的代码块中,new Throwable语句仅完成了Throwable类的实例化,整个求值过程没有将这个实例主动抛出,属于代码块的正常返回值。此时Try会顺利执行到Success(r)分支,将这个Throwable实例作为成功计算的结果封装,因此在后续模式匹配时直接命中Success(_)分支,打印输出"Success"。
触发Failure分支的正确场景
只有当代码块求值过程中真正抛出符合捕获条件的异常时,才会被Try识别为执行失败,进入Failure分支,示例:
Try( // 主动抛出Throwable实例,而非仅生成对象 throw new Throwable ) match { case Success(_) => println("Success") case Failure(exception) => exception.printStackTrace() }
上述代码执行时,会因为求值流程中抛出异常,被catch块捕获后封装为Failure,匹配到对应分支执行异常栈打印。
认知偏差说明
该场景的核心误区是将「代码块返回值为Throwable类型」和「代码块执行抛出Throwable异常」做了等同。Try的判定边界是求值过程中的异常抛出动作,而非计算结果的类型是否为Throwable。
内容的提问来源于stack exchange,提问作者Ajit Kamble
相关产品推荐
相关产品推荐

