2016-05-31 57 views
0

例如我的情况类是获取类字段

case class Test(id: String, myValues: List[Item]) 

case class Item(id: Long, order: Long) 

,我得到这样

val checkValue: String = "id" 

我想排序项测试的字符串值,我希望它看起来像

val test= Test("0", List(Item(0, 14), Item(1, 34)) 

val sortedItems = test.myValues.map(_.*checkValue*).sorted 

它关于得到像someInstanceOfClass.checkValue

回答

2

Scala不是一种解释型语言,因此您不能仅将字符串用作变量名称。为您解决问题最简单的方法是将字符串值映射到变量:

scala> def get(item: Items, str: String) = str match { 
    | case "id" => item.id 
    | case "order" => item.order 
    | } 
get: (item: Items, str: String)Long 

scala> test.myValues.map(get(_, checkValue)).sorted 
res0: List[Long] = List(0, 1) 

scala> test.myValues.map(get(_, "order")).sorted 
res1: List[Long] = List(14, 34) 

当然也有更多的方式来解决这个问题。您可以使用Reflection在运行时读取变量的名称。如果您在编译时已经知道要读取的变量的名称,则还可以使用宏来生成正在执行所需操作的代码。但是这些都是非常专业化的解决方案,我会像上面所示的那样使用运行时匹配。

1

你不妨重新考虑你如何去做这件事。字符串"id"实际上对你有什么好处?如果您只需要提取特定位数的功能,为什么不使用函数?

val f: Item => Long = _.id 

你不想一次又一次地输入函数类型吗?这也没关系;您可以使用方法来请求编译器的帮助下灌装的类型参数:

def pick[A](x: Item => A) = x 
val f = pick(_.id) 

现在你可以使用在任何地方f你会使用"id"。 (你甚至可以将它命名为id而不是f,如果这会有所帮助的话,或者可以提醒你它实际上是一个获取id的函数,而不是id本身,如idFgetId。)