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

基于蛇形命名ADT的Circe ConfiguredJsonCodec替代手动解码器咨询

解答你的Circe JSON API对接问题

1. 用@ConfiguredJsonCodec替代手动Decoder

你的核心需求是让@ConfiguredJsonCodec自动生成Foo的解码器,替代手写的fooDecoder。问题出在默认配置没有处理case object到蛇形字符串的映射,只需要调整Configuration加上构造标签的映射规则即可:

修改后的完整代码

import io.circe._
import io.circe.syntax._
import io.circe.generic.extras.{Configuration, ConfiguredJsonCodec, JsonKeys}
import io.circe.parser.parse

implicit val jsonConfig: Configuration = Configuration.default
  .withSnakeCaseConstructorNames
  .withSnakeCaseMemberNames
  .withConstructorTagMapper(JsonKeys.snakeCase) // 关键配置:把case object名转成蛇形字符串

@ConfiguredJsonCodec(decodeOnly = true)
sealed trait Foo
object Foo {
  case object FooBar extends Foo
  case object FooBaz extends Foo
  case object FooWuz extends Foo
}

@ConfiguredJsonCodec(decodeOnly = true)
case class Qux(fooFoo: List[Foo])

val input ="""{"foo_foo" : ["foo_bar", "foo_baz", "foo_wuz"]}"""
val json: Json = parse(input).left.map(println(_)).right.get
json.as[Qux] // 现在可以正常解码了!

关键说明

  • withConstructorTagMapper(JsonKeys.snakeCase)会把FooBar这类case object名称转换为foo_bar,完美匹配你的JSON格式
  • 给sealed trait Foo加上@ConfiguredJsonCodec(decodeOnly = true)后,Circe会自动生成符合配置的解码器,无需再手动实现fooDecoder
  • Qux的配置保持不变,withSnakeCaseMemberNames已经处理了fooFoo到foo_foo的字段名映射

2. 离散值建模方案讨论

用ADT + case object是非常合理的选择

这是Scala中建模无状态离散枚举值的惯用最佳实践,优势包括:

  • 类型安全:编译时就能拦截无效值,比如传入"invalid_foo"会在解码阶段报错,而如果用原始String类型则无法提前发现问题
  • 模式匹配友好:处理Foo类型时,编译器会检查是否覆盖了所有case object分支,避免遗漏场景
  • 轻量高效:case object是单例实例,运行时没有额外内存开销
  • 生态兼容:和Circe、Cats等函数式库集成顺畅,通过配置就能轻松处理命名转换、序列化/反序列化

其他可选方案(不推荐或仅适合特定场景)

  • Scala原生Enumeration:不推荐,它的类型安全性差(可以用任意Int构造枚举值),模式匹配体验不如ADT,且和Circe的集成需要额外的编码器/解码器实现
  • String类型别名:比如type Foo = String,完全丢失类型安全,无法在编译时验证值的合法性,仅适合快速原型开发
  • 带值的case class:如果你的离散值需要携带额外属性(比如显示名称、编码值),可以用case class FooBar(value: String) extends Foo,但对于单纯的标识性离散值,case object更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 22:17:53