1. ホーム
  2. scala

Scalaのケースクラスからマップへ

2023-09-08 10:56:23

質問

Scala の case class のインスタンスを変換する方法はありますか?

case class MyClass(param1: String, param2: String)
val x = MyClass("hello", "world")

をある種のマッピングに変換します。

getCCParams(x) returns "param1" -> "hello", "param2" -> "world"

これは、定義済みのものだけでなく、どのようなケースクラスに対しても機能します。例えば、基礎となる Product クラスを問い合わせるメソッドを書くことで、ケースクラスの名前を引き出すことができることがわかりました。

def getCCName(caseobj: Product) = caseobj.productPrefix 
getCCName(x) returns "MyClass"

だから私は、ケースクラスのフィールドのための同様の解決策を探しています。私は、ソリューションが Java リフレクションを使用しなければならないかもしれないと想像していますが、ケースクラスの基本的な実装が変更された場合、Scala の将来のリリースで壊れるかもしれないものを書くのは嫌です。

現在、私は Scala サーバーに取り組んでいて、プロトコルとそのすべてのメッセージと例外を case class を使って定義しています。しかし、私はそれらを Java マップに変換して、任意のクライアント実装が使用できるようにメッセージングレイヤーを介して送信する必要があります。私の現在の実装では、各ケースクラスの翻訳を個別に定義しているだけですが、一般化されたソリューションを見つけるのは素晴らしいことです。

どのように解決するのですか?

これは動作するはずです。

def getCCParams(cc: AnyRef) =
  cc.getClass.getDeclaredFields.foldLeft(Map.empty[String, Any]) { (a, f) =>
    f.setAccessible(true)
    a + (f.getName -> f.get(cc))
  }