示例案例类:正在尝试创建通用查询构建器
case class BaseQuery(operand: String, value: String)
case class ContactQuery(phone: BaseQuery, address: BaseQuery)
case class UserQuery(id: BaseQuery, name: BaseQuery, contact: ContactQuery)
val user = UserQuery(BaseQuery("equal","1"), BaseQuery("like","Foo"), ContactQuery(BaseQuery("eq","007-0000"),BaseQuery("like", "Foo City")))
//case class Contact(phone: String, address: String)
//case class User(id: Long, name: String, contact: Contact)
//val user = User(1, "Foo Dev", Contact("007-0000","Foo City"))
我们如何在 scala 中检索字段名称和相应的值,
在进一步研究中,
使用 Scala 反射的解决方案:
def classAccessors[T: TypeTag]: List[MethodSymbol] = typeOf[T].members.collect {
case m: MethodSymbol if m.isCaseAccessor => m
}.toList
// The above snippet returns the field names, and as input we have to
//feed the 'TypeTag' of the case class. And since we are only feeding a
//TypeTag we will not have access to any object values. Is there any Scala
// Reflection variant of the solution.
另一种解决方案,
def getMapFromCaseClass(cc: AnyRef) =
(scala.collection.mutable.Map[String, Any]() /: cc.getClass.getDeclaredFields)
{
(a, f) =>
f.setAccessible(true)
a + (f.getName -> f.get(cc))
}
// The above snippet returns a Map[String, Any] if we feed the case class
//object. And we will need to match the map value to any of our other case
//classes. If the class structure were simple, the above solution would be
//helpful, but in case of complex case class this would not be the most efficient solution.
尝试去:
I am actually trying to retrieve the list of field and their values during runtime.
One of the use cases,
val list: Seq[Somehow(Field+Value)] = listingFieldWithValue(obj: UserQuery)
for(o <- list){
o.field.type match{
case typeOne: FooType =>{
//Do something
}
case typeTwo: FooBarType =>{
//Do something else
}
}
}