7

Scalaケースクラスからマップへの(逆)シリアル化を実装しようとしています(field_name-> field_value)。問題は、関数を作成する方法がわからないことです。関数は、ケースクラスタイプとマップを取り、インスタンス化して、データを入力して返します。これがいくつかのJSONライブラリで行われているのを見てきましたが、コードを取得できません。

4

1 に答える 1

4

特定のケースクラスに対してこれを行うのは簡単です。

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class Foo(x: Int, y: Double, z: String) {
  def toMap = Map('x -> x, 'y -> y, 'z -> z)
}
object Foo {
  def apply(vals: Map[Symbol, Any]): Foo = Foo(vals('x).asInstanceOf[Int], vals('y).asInstanceOf[Double], vals('z).asInstanceOf[String])
}

// Exiting paste mode, now interpreting.

defined class Foo
defined module Foo

scala> Foo(Map('x -> 1, 'y -> 2.0, 'z -> "wibble"))
res0: Foo = Foo(1,2.0,wibble)

scala> res0.toMap
res1: scala.collection.immutable.Map[Symbol,Any] = Map('x -> 1, 'y -> 2.0, 'z -> wibble)

しかし、値の名前が必ずしもわからない場合に、どのケースクラスでも機能するものを作成したいと思いますか?

その場合、リフレクション(Scala 2.10.0で追加)を確認する必要があります。

http://docs.scala-lang.org/overviews/reflection/overview.html

リフレクションを使用して、クラスのメンバーを反復処理し、それらの名前が何であるかを調べてから、マップを作成できます。例えば:

scala> import reflect.runtime.universe._
import reflect.runtime.universe._

scala> typeOf[Foo].members filter { m => m.isMethod && m.asMethod.isStable }
res2: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(value z, value y, value x)
于 2013-01-13T15:28:30.757 に答える