通过字符串名称访问scala变量

时间:2018-09-06 14:17:44

标签: scala

我正在尝试使用其值在运行时确定的字符串访问对象的变量。

基本上,该对象用作字典,现在我要动态轮询该字典中的值

一个简化的示例:

object Something extends scala.AnyRef {
    final val zero = 0
    final val one = 1
    final val two = 2
}

然后我主要想执行以下操作

Somthing."zero"

并获得0作为回报。

理想情况下,我想为此使用scala反射

2 个答案:

答案 0 :(得分:1)

警告:在听取我的回答之前,请听取JörgW Mittag的建议:

  

Scala非常喜欢类型安全的编译时反射。因此,使用   以这种方式进行反射不是Scala方式。斯卡拉方式   可能是使用编译时反射来生成所有这些   模式匹配案例

使用反射Something.getClass.getDeclaredMethods.foreach(println)可以得出:

public final int example.Something$.zero()
public final int example.Something$.one()
public final int example.Something$.two()

所以要获得我们可以做的名字

Something.getClass.getDeclaredMethods.map(_.getName) // Array(zero,one,two)

并获取值

Something.getClass.getMethod("zero").invoke(Something) // 0

定义以下implicit class

implicit class AccessMembersByReflectionName(something: Something.type) {
  def get(name: String): AnyRef = {
    Something.getClass.getMethod(name).invoke(Something)
  }
}

清理呼叫站点

Something.get("zero") // 0

答案 1 :(得分:0)

@ n.m。已经指出,如果您只想在给定字符串键的情况下检索相同类型的值,则应使用字典。

但是,如果由于某种原因仍然需要对象,则可以使用此方法完成所需的操作。

Object Something {
  val Zero: Int  = 0
  val One: Int   = 1
  val Three: Int = 3

  def getValueByString(valName: String): Int = valName.toLowerCase match {
    case "zero"  => Zero
    case "one"   => One
    case "three" => Three
  }
}  

编辑 我刚刚读到可以修改对象,仍然可以创建一个函数来接收对象和valName作为字符串。