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

Scala 3如何获取Case Class的字段类型并转为List?

解决Scala获取Case Class字段类型列表的问题

错误原因分析

  • 版本一错误:summonInline[head]是尝试获取head类型的给定实例(比如需要存在given String这样的隐式值),但我们的需求是获取类型信息而非实例,方向完全错误,导致找不到对应类型的给定实例报错。
  • 版本二错误:constValue[head]仅适用于常量类型(如字面量类型1、"test"),而Case Class的字段类型是普通的类型(如String、Int),不符合constValue的使用条件,因此报错。

正确实现方案

要在编译期获取Case Class的字段类型并转为字符串列表,需利用Scala 3的内联和镜像机制,通过typeOf获取类型元数据来实现:

import scala.deriving.Mirror
import scala.compiletime.{erasedValue, typeOf}

transparent inline def getClassesFieldType[A](using p: Mirror.ProductOf[A]): List[String] =
  summonFieldTypes[p.MirroredElemTypes]

transparent inline def summonFieldTypes[T <: Tuple]: List[String] =
  inline erasedValue[T] match
    case _: (head *: tail) =>
      // 获取Scala风格的类型名称(如String、Int)
      typeOf[head].typeSymbol.name.toString :: summonFieldTypes[tail]
    case _ => Nil

代码说明

  1. Mirror.ProductOf[A]:Scala 3的镜像类型,用于获取Case Class的元数据,p.MirroredElemTypes是该Case Class所有字段类型组成的Tuple类型。
  2. 内联递归处理Tuple:summonFieldTypes通过内联匹配Tuple的head *: tail结构,递归遍历所有字段类型。
  3. 获取类型名称:typeOf[head]获取类型的元数据对象,typeSymbol.name提取Scala风格的类型名称(若需要完整的全限定类名,直接使用typeOf[head].toString即可)。

测试示例

case class Tester(name: String, age: Int, active: Boolean)

// 输出:List(String, Int, Boolean)
println(getClassesFieldType[Tester])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 08:12:43