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

使用com-lihaoyi/PPrint打印case class属性名遇挫求助

解决com-lihaoyi/PPrint打印case class带属性名的问题

错误原因

你的代码抛出MatchError是因为productIterator.toSeq.map里用了case (name, value)模式匹配,但productIterator返回的是case class属性值的迭代器,不是键值对元组,匹配失败导致报错。

可行解决方案

要打印case class的属性名,需要把case class的字段名和对应的值配对。Scala 2.13及以上版本可直接用productElementNames获取字段名,结合productIterator的值构造带属性名的输出;同时要递归调用自定义处理器,保证嵌套结构也能正确处理。

修正后的代码:

import fansi.Str
import pprint._

object Testo extends App {

  case class Person(name: String, age: Int, address: Address)
  case class Address(street: String, city: String)

  val person = Person("John Doe", 30, Address("123 Main St", "New York"))
  val list = List(person, person)
  val map2 = Map("foo" -> list, "bar" -> person)

  val pprint2 = pprint.copy(
    additionalHandlers = {
      case p: Product if p.productArity > 0 =>
        // 配对字段名与对应属性值
        val fieldPairs = p.productElementNames.zip(p.productIterator)
        // 递归处理每个属性值,保留pprint的格式化特性
        val fieldTrees = fieldPairs.map { case (name, value) =>
          Tree.Apply(
            Tree.Literal(fansi.Str(s"$name = ")),
            List(walker.treeify(value, pprint2))
          )
        }
        // 构造case class的树形输出结构
        Tree.Apply(
          Tree.Literal(fansi.Str(p.productPrefix)),
          List(Tree.Tuple(fieldTrees.toList))
        )
    }
  )

  // 打印最终结果
  pprint2.pprintln(map2)
}

关键细节说明

  • productElementNames:Scala 2.13引入的方法,直接返回case class的字段名迭代器,无需反射,简洁高效。若使用Scala 2.12及以下版本,需通过反射API获取字段名(比如p.getClass.getDeclaredFields.map(_.getName)),注意过滤编译器生成的冗余字段(如MODULE$)。
  • 递归处理嵌套结构:用walker.treeify(value, pprint2)递归处理每个属性值,确保嵌套的case class(如示例中的Address)也能打印出属性名。
  • 保留格式化特性:避免直接拼接字符串返回Literal,而是构造Tree.Apply和Tree.Tuple结构,让pprint保持原有的换行、缩进等格式化能力。
  • showFieldNames参数:该参数针对pprint内置类型(如Map键值对)生效,无法控制case class的属性名显示,因此之前设置该参数无效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:22:48