这是对以下问题的跟进:Fastest way to get the names of the fields of a case class in Scala
我正在尝试找到一种提供快速自定义序列化的简单方法(比如说(String, Object)
的元组列表,它可以转换为生产中的db行或单元测试中的内存映射)对于Scala中的一类案例类,似乎保留一个类的字段的缓存列表可能是一种很有前途的方法。但是,我不确定最干净的方法。我知道我可以做以下事情:
case class Playlist(
val id: Option[Long],
val title: Option[String],
val album: Option[String],
val artist: Option[String],
val songId: Option[UUID]) {
def serialize = Playlist.fields.map(f => (f.getName, f.get(this)))
}
object Playlist {
val empty = Playlist(None, None, None, None, None)
val fields = Playlist.empty.getClass.getDeclaredFields.toList
fields foreach { _.setAccessible(true) }
}
但是有一些我不喜欢的事情:
empty
来获取缓存的字段列表在Scala中实现这一目标的最简洁方法是什么?
答案 0 :(得分:2)
我认为将Class[_] -> fields
的缓存映射与任何单个案例类分开是最简单的,例如在具有方法serialize(instance)
的全局单例中。这样您就不必在要序列化的类中编写任何额外的代码。
另一种方法是创建一个特质来混合案例类'伴随对象,具有缓存的字段列表,以及用于添加serialize
方法的隐式包装类。您可以使用隐式ClassTag
初始化fields
:
abstract class MyCompanion[T](implicit ctag: ClassTag[T]) {
private val fields = ctag.runtimeClass.getDeclaredFields.toList
fields foreach { _.setAccessible(true) }
implicit class AddSerializeMethod(obj: T) {
def serialize = fields.map(f => (f.getName, f.get(obj)))
}
}
case class C(...) { ... }
object C extends MyCompanion[C]
不幸的是,您似乎无法通过这种方式使AddSerializeMethod
成为价值类。