Lift-JSON序列化的案例类层次结构

3

我有一个层次结构,类似于以下内容:

case class A(val a: Long, val b: String)

case class B(val c: String) extends A(a=3, b="a string")

我正在尝试使用lift-json将其序列化,如下所示:

val obj = B(c="another string")
val cameraJson = net.liftweb.json.Serialization.write(obj)

但是我看到的是,它只序列化了类B中的属性,而没有序列化类A中的属性。

我也尝试过:

compact(render(decompose(obj)))

有同样的结果是什么意思?我是否遗漏了Scala中显而易见的内容?

3个回答

8

Scala的案例类继承是一个已弃用的功能。例如,应该使用以下代码:

trait A { val a: Long; val b: String }
case class B(a: Long = 3, b: String = "a string", c: String) extends A

val obj = B(c="another string")
var ser = Serialization.write(obj)
Serialization.read[B](ser)

4
一个小的精确性说明:已弃用的是一些特例情况下的类继承。你仍然可以使用标准类来继承一个 case 类。 - Nicolas

5

对于case class的经典lift JSON序列化,它是基于构造函数参数列表实现的(参见decompose implementation),而不是类属性。因此,您必须要么覆盖父trait中声明的所有字段(就像@Joni答案中所示),要么使用组合而不是继承。

例如:


case class A(a: Long, b: String)
case class B(c: String, a: A = A(a=3, b="a string"))
B(c="another string")

顺便说一下,在case类构造函数中使用val关键字是不必要的。通过将类声明为case类,您可以免费获得每个构造函数参数的访问器之一,这是其中的一个好处


在案例类中,默认情况下,所有构造函数参数都是val类型,这样说更有帮助。 - Caoilte

3

我认为只对c进行序列化是正确的做法。序列化中出现的信息将是类型为B和C的值。a和b的值由类型为B的信息暗示。它们分别为3和"a string",不可能是其他值,因此不需要写入。

从对源代码的粗略查看中,其默认行为是序列化与主构造函数参数相对应的字段。


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