如何最好地保存一个成员字段的缓存列表,每个字段对应Scala中的case类族



这是以下问题的后续:在Scala中获取case类字段名的最快方法

我正试图找到一种简单的方法来提供快速自定义序列化(让我们说到(String, Object)的元组列表,它可以在生产中转换为db行或在单元测试中转换为内存映射)到Scala中的case类家族,似乎保持类字段的缓存列表可能是一种很有前途的方法。然而,我不确定最干净的方法是什么。我知道我可以做如下的事情:

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) }
}

然而,我不喜欢这一点:

  1. 我不想从同伴类中使用empty只是为了获得缓存的字段列表
  2. 我不想为每个我想要序列化行为的case类声明序列化逻辑。可能有一些方法可以绕过这个问题,但我不确定最干净的方法会给出正确的行为(担心混合反射和继承)

在Scala中实现这个最干净的方法是什么?

我认为将Class[_] -> fields的缓存映射与任何个案类分开是最简单的,例如在具有serialize(instance)方法的全局单例中。这样,您就不必在希望序列化的类中编写任何额外的代码。

另一种方法可能是创建一个trait来混合case类的同伴对象,缓存字段列表,以及一个隐式包装类来添加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一个值类的这种方式。

相关内容

  • 没有找到相关文章

最新更新