首页 > 解决方案 > Scala: How to create a class method which return class variable value by taking variable name as string input

问题描述

I'm new to Scala, and I'm trying to write a class method in Scala which takes the class variable name (as string) as input and returns that variable value. Say I have a class Person with variables name and age.

I need a method getVar in class Person which can do

//Expected output in comments next to a method call

val p1 = new Person(name="abc",age=23);
p1.getVar("age"); //Returns 23
p1.getVar("name"); //Returns "abc" 

I don't know how do I refer to that class variable by name in getVar method. Any help would be appreciated

标签: scalaclass

解决方案


You can use reflection.

import scala.reflect.ClassTag
import scala.reflect.runtime.universe._

abstract class FieldRequestSupport[SelfType <: Product : ClassTag : TypeTag] {
    self: SelfType =>

    private val classFieldsAccessors: Map[String, MethodSymbol] = typeOf[SelfType].members.collect({
        case m: MethodSymbol if m.isCaseAccessor => m
    }).flatMap(symbol => TermName.unapply(symbol.name).map((_, symbol)))(collection.breakOut)
    private val classMirror: Mirror = runtimeMirror(getClass.getClassLoader)

    def requestField(fieldName: String): Option[Any] = {
        classFieldsAccessors.get(fieldName).map(
            symbol => classMirror.reflect(self).reflectField(symbol).get
        )
    }
}

case class Person(name: String, age: Int) extends FieldRequestSupport[Person]

object Test extends App {
    val person = Person("Bob", 26)
    println(person.requestField("name")) //will print Some(Bob)
    println(person.requestField("age")) //will print Some(26)
    println(person.requestField("qqq")) //will print None
}

推荐阅读