You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Play JSON密封特质类型的隐式解析问题

问题描述

定义了一个被CaseClass1、CaseClass2两个样例类实现的密封特质MySealedTrait,并编写了针对该特质的隐式Writes:

implicit val myCaseClassWrites: Writes[MySealedTrait] = Writes {
  case CaseClass1(a, b, c) => Json.toJson(
    a,
    b,
    c
  )
  case CaseClass2(a, b, c, d) => Json.toJson(
    a,
    b,
    c,
    d
  )
}

在控制器中以JSON形式返回响应时,编译报错:

No Json serializer found for type com.mypackage.CaseClass2. Try to implement an implicit Writes or Format for this type

为CaseClass2编写显式Writes后,问题解决:

implicit val caseClass2JSONWrites: Writes[CaseClass2] = Writes { caseClass2 =>
  Json.toJson(caseClass2.a,
    caseClass2.b,
    caseClass2.c,
    caseClass2.d
  )
}

请问该现象的原因是什么?

原因分析
  • Scala隐式解析优先匹配最具体的类型:当直接返回CaseClass2类型的实例时,编译器会优先寻找针对CaseClass2的隐式Writes,而非向上查找父特质MySealedTrait的Writes。最初仅定义了父特质的序列化器,导致编译器找不到对应CaseClass2的序列化逻辑,触发报错。
  • 父特质的Writes[MySealedTrait]仅适用于声明为MySealedTrait类型的实例:如果控制器返回值被显式声明为MySealedTrait类型(比如val response: MySealedTrait = CaseClass2(...)),编译器才会使用父特质的Writes。但返回原始CaseClass2类型时,编译器不会自动向上匹配父特质的序列化器。
  • 显式添加Writes[CaseClass2]后,编译器找到了对应具体类型的隐式序列化器,报错消失。另外也可以不用单独编写该序列化器,只要将返回的CaseClass2实例显式转换为MySealedTrait类型,同样能复用父特质的Writes逻辑。

内容的提问来源于stack exchange,提问作者joesan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:52:46