3

私は次のような階層を持っています:

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

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

そして私はlift-jsonalaを使用してそれをシリアル化しようとしています:

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

しかし、私が見ているのは、クラスBのプロパティのみをシリアル化し、Aのプロパティはシリアル化しないということです。

私も試しました:

compact(render(decompose(obj)))

同じ結果で

何が得られますか?Scalaに私が見逃している明らかなものはありますか?

4

3 に答える 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)
于 2011-09-01T06:44:13.240 に答える
5

ケースクラスの従来のリフトJSONシリアル化は、クラス属性ではなく、コンストラクター引数リスト(分解の実装を参照)に基づいています。したがって、親トレイトで宣言されているすべてのフィールドをオーバーライドするか(@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")

ところでval、クラスコンストラクタが不要な場合のキーワード。すべてのコンストラクターargのアクセサーは、クラスをケースとして宣言することで無料で入手できるものの1つです。

于 2011-09-01T06:58:25.920 に答える
3

cのみをシリアル化するIMOは正しいことのようです。シリアル化に表示される情報は、タイプがBでCの値です。aとbの値は、情報タイプがBであることを意味します。これらは3であり、「文字列」であり、他には何もありません。書く必要はありません。

ソースコードをざっと見てみると、デフォルトの動作は、プライマリコンストラクタのパラメータに対応するフィールドをシリアル化することです。

于 2011-09-01T07:01:24.270 に答える