K.Alan
K.Alan

Reputation: 200

how to display value of case class in scala

case class Keyword(id: Int = 0, words: String)

val my= Keyword(123, "hello")

val fields: Array[Field] = my.getClass.getDeclaredFields

for (i <- fields.indices) {

  println(fields(i).getName +":"+ my.productElement(i))

}

id:123

title:keyword's title

it's ok.

def outputCaseClass[A](obj:A){

  val fields: Array[Field] = obj.getClass.getDeclaredFields

  for (i <- fields.indices) {

    println(fields(i).getName +":"+ obj.productElement(i))

  }
}

outputCaseClass(my)

it's wrong

Upvotes: 0

Views: 2155

Answers (2)

sarveshseri
sarveshseri

Reputation: 13985

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

def printCaseClassParams[C: scala.reflect.ClassTag](instance: C):Unit = {
  val runtimeMirror = ru.runtimeMirror(instance.getClass.getClassLoader)
  val instanceMirror = runtimeMirror.reflect(instance)
  val tpe = instanceMirror.symbol.toType

  tpe.members
    .filter(member => member.asTerm.isCaseAccessor && member.asTerm.isMethod)
    .map(member => {
      val term = member.asTerm
      val termName = term.name.toString
      val termValue = instanceMirror.reflectField(term).get
      termName + ":" + termValue
    })
    .toList
    .reverse
    .foreach(s => println(s))
}

// Now you can use it with any case classes,

case class Keyword(id: Int = 0, words: String)

val my = Keyword(123, "hello")

printCaseClassParams(my)
// id:123
// words:hello

Upvotes: 3

nob
nob

Reputation: 1414

productElement is a Method of the Product Base trait.

Try to use a method signature like this:

def outputCaseClass[A <: Product](obj:A){ .. }

However it still won't work for inner case classes (fields also reports the $outer-Field, which productElement won't return and so it crashes with IndexOutOfBoundsException).

Upvotes: 2

Related Questions