获取类字段
问题描述:
例如我的情况类是获取类字段
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
答
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在运行时读取变量的名称。如果您在编译时已经知道要读取的变量的名称,则还可以使用宏来生成正在执行所需操作的代码。但是这些都是非常专业化的解决方案,我会像上面所示的那样使用运行时匹配。
答
你不妨重新考虑你如何去做这件事。字符串"id"
实际上对你有什么好处?如果您只需要提取特定位数的功能,为什么不使用函数?
val f: Item => Long = _.id
你不想一次又一次地输入函数类型吗?这也没关系;您可以使用方法来请求编译器的帮助下灌装的类型参数:
def pick[A](x: Item => A) = x
val f = pick(_.id)
现在你可以使用在任何地方f
你会使用"id"
。 (你甚至可以将它命名为id
而不是f
,如果这会有所帮助的话,或者可以提醒你它实际上是一个获取id的函数,而不是id本身,如idF
或getId
。)