我有一个案例类:
case class A(field1: String, field2: Int)
我想在某些代码中引用确切的字符串“field1”,如:
val q = Query("field1"-> "hello")
performQuery(q)
现在我必须小心,我一直正确输入“field1”。为避免这种情况,我想使用对A.field1
的引用作为字符串,如下所示:
val q = Query(A.field1 -> "hello")
performQuery(q)
这将帮助我避免任何输入错误,而且如果我稍后重命名这些字段,我不需要更新其余的代码库字符串。我可以依靠IDE。
如何将案例类字段名称提取为字符串?
EDIT1
以下是用法的另一种变体:
// capture the field name
val FIELD1_NAME = A.field1 // this implementation can change
此时FIELD1_NAME
应包含"field1"
字符串
// Now use the string obtained above to create a query:
val q = Query(FIELD1_NAME -> "hello")
performQuery(q)
答案 0 :(得分:1)
找到https://gist.github.com/dwickern/b47606a1ed2319afa6e2:
import scala.annotation.tailrec
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
object Macros {
def nameOfImpl(c: blackbox.Context)(x: c.Tree): c.Tree = {
import c.universe._
@tailrec def extract(x: c.Tree): String = x match {
case Ident(TermName(s)) => s
case Select(_, TermName(s)) => s
case Function(_, body) => extract(body)
case Block(_, expr) => extract(expr)
case Apply(func, _) => extract(func)
}
val name = extract(x)
q"$name"
}
def nameOfMemberImpl(c: blackbox.Context)(f: c.Tree): c.Tree = nameOfImpl(c)(f)
def nameOf(x: Any): String = macro nameOfImpl
def nameOf[T](f: T => Any): String = macro nameOfMemberImpl
}
//
// Sample usage:
//
val someVariable = ""
Macros.nameOf(someVariable) // "someVariable"
def someFunction(x: Int): String = ???
Macros.nameOf(someFunction _) // "someFunction"
case class SomeClass(someParam: String)
val myClass = SomeClass("")
Macros.nameOf(myClass.someParam) // "someParam"
// without having an instance of the class:
Macros.nameOf[SomeClass](_.someParam) // "someParam"
对于您的用例,Query(nameOf[A](_.field1) -> "hello")
。