2015-04-08 153 views
0

我有了一些瓦爾斯給它的課,我需要的是基於在模式字符串匹配到現場

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}} 
    } 
} 

謝謝。

+0

第二種方法在這裏並不適用。我認爲按名稱查找'AThing'的唯一方法是在'List'中使用val並使用'find'。 –

回答

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")

+0

感謝您的建議,理想情況下不會希望地圖解決方案,因爲這將意味着大量的重複,當它是一個相當簡單的功能,會給其他人一個去 – andyroo