模式将字符串匹配到字段

时间:2015-04-08 12:44:50

标签: scala scala-2.10

我有一个类有一些val,我需要一个函数根据传入的字符串返回val

case class AThing(name: String, description: String)

object AThing {

  val FIRST_THING = AThing("FIRST_THING", "A first thing desc")
  val SECOND_THING = AThing("SECOND_THING", "A second thing desc")
  val THIRD_THING = AThing("THIRD_THING", "A third thing desc")

}

现在我有以下解决方案:

def get(name: String): AThing = {

  name match {
    case "FIRST_THING"   => FIRST_THING
    case "SECOND_THING"  => SECOND_THING
    case "THIRD_THING"   => THIRD_THING
  }

}

这是否有更好的模式..我发誓我记得看到了类似的内容:

def get(name: String): AThing = {
  name match {
    case `name` => AThing.`name`
    // OR
    case `name` => AThing.{{name}}
  }
}

感谢。

1 个答案:

答案 0 :(得分:3)

您可以使用Java反射来获取字段:

def get(name: String): AThing = 
  AThing.getClass.getDeclaredMethod(name).invoke(AThing).asInstanceOf[AThing]

作为object AThing的方法,您也可以使用此格式:

object AThing {
  val FIRST_THING = ???
  // ... other things

  def get(name: String) = 
    this.getClass.getDeclaredField(name).get(this).asInstanceOf[AThing]
}

或者使用Scala反射:

import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
def get(name: String) = 
  currentMirror.reflect(AThing)
               .reflectField(typeOf[AThing.type].member(TermName(name)).asTerm)
               .get.asInstanceOf[AThing]

为了增加安全性,您可以返回Option

def getOption(name: String): Option[AThing] = util.Try(get(name)).toOption

但也考虑使用Map

对此概念进行建模
object AThing {
  val things: Map[String, AThing] = Seq(
    AThing("FIRST_THING", "A first thing desc"),
    AThing("SECOND_THING", "A second thing desc"),
    AThing("THIRD_THING", "A third thing desc")
  ).map(thing => thing.name -> thing).toMap
}

然后,您可以使用AThing.things("FIRST_THING")按名称获取内容,或者获取OptionAThing.things.get("FIRST_THING")