Magnolia Tech

いつもコードのことばかり考えている人のために。

Scalaのコンストラクタのフィールドを取得する

コンストラクタのフィールドを得る方法について

import scala.reflect.runtime.{universe => ru}
import ru._

class Person(val name: String, age: Int, blah: List[Int])

object ReflectionTest {
  def main(args: Array[String]): Unit = {

    def generate[T](implicit tag: TypeTag[T]): Unit = {

      val typeSymbol          = typeOf[T].typeSymbol            // 型のSymbolを得る
      val constructorSymbol = typeSymbol.asClass.typeSignature.decl(termNames.CONSTRUCTOR).asMethod // コンストラクタ

      val list = constructorSymbol.paramLists(0)  // Listが空の時は、def test = {}みたいな定義が行われているとき

      // https://stackoverflow.com/questions/27473440/scala-get-constructor-parameters-at-runtime
      val params = list.reverse.foldRight(Map(): Map[String, ru.Type])((p, a) => {
        a + (p.name.decodedName.toString -> p.typeSignature)
      })

      params.foreach { p => println(p) }
    }

    generate[Person]
  }
}