Scala中将case class转换为map

78

有没有一种简便的方法可以将Scala的case class实例转换成其他类型,例如

case class MyClass(param1: String, param2: String)
val x = MyClass("hello", "world")

转换成某种映射,例如

getCCParams(x) returns "param1" -> "hello", "param2" -> "world"

这适用于任何情况类,不仅限于预定义的类。我发现可以通过编写一个检查底层Product类的方法来提取情况类名称,例如:

def getCCName(caseobj: Product) = caseobj.productPrefix 
getCCName(x) returns "MyClass"

我在寻找一个类似的解决方案,但是针对case class字段。我想这个解决方案可能需要使用Java反射,但如果case classes的底层实现发生更改,我不希望编写的代码在Scala未来版本中出现问题。

目前,我正在开发一个Scala服务器,并使用case classes定义协议及其所有消息和异常,因为它们非常适合这种美丽且简洁的结构。但是,我需要将它们转换成Java映射以便于发送给任何客户端实现的消息传输层。我的当前实现只是分别为每个case class定义了一个翻译,但是找到一个通用的解决方案会很好。


我发现了这篇博客文章,它展示了如何使用宏来完成此操作。 - Giovanni Botta
12个回答

2

0

使用Scala 3的现代变体可能会更加简化,例如以下示例与Walter Chang上面发布的答案类似。

def getCCParams(cc: AnyRef): Map[String, Any] =
  cc.getClass.getDeclaredFields
    .tapEach(_.setAccessible(true))
    .foldLeft(Map.empty)((a, f) => a + (f.getName -> f.get(cc)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接