Scala 宏调用编译时确定的函数名
Scala macros invoke a compile-time determined function name
我有以下代码:
def invokeFunction(logger: Logger, fName: String) = macro invokeFunctionImpl
//...
def invokeFunctionImpl(c: Context)(logger: c.Expr[Logger], fName: c.Expr[String]) ={
import c.universe._
// i'd like to invoke: logger.${fName}("some message")
}
我面临的另一个问题是在编译时使用给定参数命名函数:
def createFunction(fName: String) = macro createFunctionImpl
//...
def createFunctionImpl(c: Context)(fName: c.Expr[String], param: c.Expr[String]) ={
import c.universe._
// i'd like to create: def functionNamed${fName}(param: [paramType]) = {
// implementation unimportant
}
如有任何帮助,我们将不胜感激。
invokeFunction
应该是
def invokeFunction(logger: Logger, fName: String): Unit = macro invokeFunctionImpl
def invokeFunctionImpl(c: blackbox.Context)(logger: c.Expr[Logger], fName: c.Expr[String]): c.Expr[Unit] ={
import c.universe._
val q"${fNameStr: String}" = fName.tree
c.Expr(q"""$logger.${TermName(fNameStr)}("some message")""")
}
我添加了 return 类型。我假设 fName
是 compile-time String
文字(否则你会得到 MatchError
)。
关于createFunction
尝试
def createFunction(fName: String, param: String): Unit = macro createFunctionImpl
def createFunctionImpl(c: blackbox.Context)(fName: c.Expr[String], param: c.Expr[String]): c.Expr[Unit] ={
import c.universe._
val q"${fNameStr: String}" = fName.tree
val q"${paramNameStr: String}" = param.tree
c.Expr(q"""
def ${TermName(fNameStr)}(${TermName(paramNameStr)}: ParamType) = ???
()
""")
}
请注意宏的签名和它的实现必须一一对应。所以我将 param
添加到 createFunction
。我添加了 return 类型。同样重要的是,正在创建的函数只能在我们的宏扩展到的块内访问。新定义不是 def macros are normally intended for (macro annotations 的定义)。
我不确定我是否完全理解你在做什么。如果您提供您将如何使用宏的代码,将更容易回答。
我有以下代码:
def invokeFunction(logger: Logger, fName: String) = macro invokeFunctionImpl
//...
def invokeFunctionImpl(c: Context)(logger: c.Expr[Logger], fName: c.Expr[String]) ={
import c.universe._
// i'd like to invoke: logger.${fName}("some message")
}
我面临的另一个问题是在编译时使用给定参数命名函数:
def createFunction(fName: String) = macro createFunctionImpl
//...
def createFunctionImpl(c: Context)(fName: c.Expr[String], param: c.Expr[String]) ={
import c.universe._
// i'd like to create: def functionNamed${fName}(param: [paramType]) = {
// implementation unimportant
}
如有任何帮助,我们将不胜感激。
invokeFunction
应该是
def invokeFunction(logger: Logger, fName: String): Unit = macro invokeFunctionImpl
def invokeFunctionImpl(c: blackbox.Context)(logger: c.Expr[Logger], fName: c.Expr[String]): c.Expr[Unit] ={
import c.universe._
val q"${fNameStr: String}" = fName.tree
c.Expr(q"""$logger.${TermName(fNameStr)}("some message")""")
}
我添加了 return 类型。我假设 fName
是 compile-time String
文字(否则你会得到 MatchError
)。
关于createFunction
尝试
def createFunction(fName: String, param: String): Unit = macro createFunctionImpl
def createFunctionImpl(c: blackbox.Context)(fName: c.Expr[String], param: c.Expr[String]): c.Expr[Unit] ={
import c.universe._
val q"${fNameStr: String}" = fName.tree
val q"${paramNameStr: String}" = param.tree
c.Expr(q"""
def ${TermName(fNameStr)}(${TermName(paramNameStr)}: ParamType) = ???
()
""")
}
请注意宏的签名和它的实现必须一一对应。所以我将 param
添加到 createFunction
。我添加了 return 类型。同样重要的是,正在创建的函数只能在我们的宏扩展到的块内访问。新定义不是 def macros are normally intended for (macro annotations 的定义)。
我不确定我是否完全理解你在做什么。如果您提供您将如何使用宏的代码,将更容易回答。