按字符串名称访问 scala 变量



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

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

一个简化的示例:

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

然后,我主要想做以下几点

Somthing."zero"

并得到 0 作为回报。

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

警告:在遵循我的回答之前,请听从Jörg W Mittag的建议:

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 AccessMembersByReflectionName(something: Something.type) {
def get(name: String): AnyRef = {
Something.getClass.getMethod(name).invoke(Something)
}
}

清理呼叫站点

Something.get("zero") // 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 作为字符串。