Scala伴生对象编写toFirstOrSecond调用Try报does not take parameters错误
问题排查与解决
你正尝试编写toFirstOrSecond方法实现类似Try的异常捕获效果,当前代码如下:
object A: enum FirstOrSecond[+V]: case First(x: V) extends FirstOrSecond[V] case Second(e : Throwable) extends FirstOrSecond[V] def map[Q](f: V ⇒ Q): FirstOrSecond[Q] = this match case FirstOrSecond.Second(e) ⇒ FirstOrSecond.Second(e) case FirstOrSecond.First(v) ⇒ Try { FirstOrSecond.First(f(v)) }.toFirstOrSecond match case FirstOrSecond.First(m) => FirstOrSecond.First(f(v)) case FirstOrSecond.Second(m) => FirstOrSecond.Second(m) object Try: def toFirstOrSecond[Q](f: Try[Q]): FirstOrSecond[Q] = f match case Failure(e) => FirstOrSecond.First(e) case Success(v) => FirstOrSecond.Second(v)
运行时触发报错:object Try in object A does not take parameters。
核心问题
- 作用域遮蔽导致调用失败:你在
A对象内部自定义了名为Try的单例,优先级高于Scala标准库的scala.util.Try。这个内部自定义的Try对象没有实现可接收代码块的apply方法,因此编译器会把Try { ... }识别为对这个空单例的无意义传参调用,触发报错。 - 枚举分支语义颠倒:按照枚举定义,
First应承载正常计算结果、Second应承载计算抛出的异常,但你写的toFirstOrSecond转换逻辑把异常(Failure)映射到了First分支、把正常值(Success)映射到了Second分支,和定义完全相悖。 - map方法逻辑冗余错配:map分支内嵌套了多层无意义的匹配逻辑,还重复执行了两次
f(v),就算解决了Try的调用问题,最终输出也不符合预期。
修复步骤
- 删除内部自定义的空
Try单例,导入Scala标准库的scala.util.Try、Success、Failure,直接复用标准库Try的异常捕获能力。 - 修正
toFirstOrSecond的映射规则,匹配枚举本身的语义:异常值对应Second分支,正常值对应First分支。 - 简化map方法实现,去掉冗余的重复逻辑,直接调用转换方法得到对应枚举分支即可。
修复后的可运行参考代码:
import scala.util.{Try, Success, Failure} object A: enum FirstOrSecond[+V]: case First(x: V) extends FirstOrSecond[V] case Second(e : Throwable) extends FirstOrSecond[V] def map[Q](f: V ⇒ Q): FirstOrSecond[Q] = this match case Second(e) => Second(e) case First(v) => Try(f(v)).toFirstOrSecond // 为Try类型添加扩展转换方法 extension [Q](t: Try[Q]) def toFirstOrSecond: FirstOrSecond[Q] = t match case Failure(e) => Second(e) case Success(v) => First(v)
内容的提问来源于stack exchange,提问作者user13033677
相关产品推荐
相关产品推荐

