带有新标识符的scala宏
我有一个宏,我想用它来记录执行一个可能返回有用信息的块所需的时间。所以如果我有带有新标识符的scala宏,scala,macros,scala-quasiquotes,Scala,Macros,Scala Quasiquotes,我有一个宏,我想用它来记录执行一个可能返回有用信息的块所需的时间。所以如果我有 val y=f(x)我将更改为val y=Timed(f(x))以获取在日志中执行函数所需的时间 我几乎得到了我想要的,但是当使用新的术语名称来避免名称冲突时,例如t0和t1之间,我得到了一个错误: Error:(22, 15) Can't unquote reflect.runtime.universe.TermName, consider providing an implicit instance of Lif
val y=f(x)
我将更改为val y=Timed(f(x))
以获取在日志中执行函数所需的时间
我几乎得到了我想要的,但是当使用新的术语名称来避免名称冲突时,例如t0和t1之间,我得到了一个错误:
Error:(22, 15) Can't unquote reflect.runtime.universe.TermName, consider providing an implicit instance of Liftable[reflect.runtime.universe.TermName]
val $kk = System.nanoTime()
^
如何让那些FreshTerm的名字和Quasikotes一起工作
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
import scala.reflect.runtime.{ universe ⇒ u }
object Timed {
def apply[T](block: ⇒ T): T = macro Timed.apply_impl[T]
def apply_impl[T: c.WeakTypeTag](c: Context)(block: c.Expr[T]): c.Expr[T] = {
import c.universe._
implicit val cc: c.type = c
val kk = u.internal.reificationSupport.freshTermName("kk")
val t0 = c.freshName("t0")
val t1 = c.freshName("t1")
val tdiff = c.freshName("tdiff")
val blk = c.freshName("blk")
val t0n = "t0"
println(t0)
val res = c.Expr(
q"""
val $kk = System.nanoTime()
$block
val t1 = System.nanoTime()
val tdiff= t1 - t0
log.debug("Took: {}", tdiff)
$block
""")
println("Timing block: ")
println(show(res))
res
}
}
您不需要
术语名
,您需要的是标识
:
val kk = Ident(TermName("kk"))
但是,如果标识符的名称是常量,那么就没有理由这样构造标识符,而您可以这样写:
q"""
val kk = System.nanoTime
...
"""
改变这一点可以解决这个问题,但还有其他问题t0
在Quasikotes中未定义,并且您定义的所有其他术语名称实际上没有任何作用
我也不明白为什么你需要一个宏,当一个普通的方法做得很好的时候。宏将增加代码的大小(如果您经常使用它,则会显著增加)