模式匹配一个字符串到一个字段
Pattern match a string to a field
我有一个 class 有一些 vals,我需要一个函数 returns vals 基于传入的字符串
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}}
}
}
谢谢。
可以使用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]
为了增加安全性,您可以将其 return 设为 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")
按名称获取事物,或获取 Option
:AThing.things.get("FIRST_THING")
.
我有一个 class 有一些 vals,我需要一个函数 returns vals 基于传入的字符串
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}}
}
}
谢谢。
可以使用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]
为了增加安全性,您可以将其 return 设为 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")
按名称获取事物,或获取 Option
:AThing.things.get("FIRST_THING")
.