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
代码说明
Mirror.ProductOf[A]:Scala 3的镜像类型,用于获取Case Class的元数据,p.MirroredElemTypes是该Case Class所有字段类型组成的Tuple类型。- 内联递归处理Tuple:
summonFieldTypes通过内联匹配Tuple的head *: tail结构,递归遍历所有字段类型。 - 获取类型名称:
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
相关产品推荐
相关产品推荐

