如何匹配 return 一个 Future 并具有多个参数或多个参数列表(curried)的方法?
How to match methods which return a Future and have multiple arguments or multiple arguments list (curried)?
我正在玩 scalameta,我想要一个通用的测量注释,它发送有关方法执行时间的测量值。
我用的是Qing Wei的缓存注解demo。
https://www.cakesolutions.net/teamblogs/scalameta-tut-cache
它适用于非异步方法,但由于 ExecutionContext 参数列表,我的属性与 return Future 的方法不匹配。
我的注释如下所示:
package measurements
import scala.concurrent.Future
import scala.meta._
class measure(name: String) extends scala.annotation.StaticAnnotation {
inline def apply(defn: Any): Any = meta {
defn match {
case defn: Defn.Def => {
this match {
case q"new $_($backendParam)" =>
val body: Term = MeasureMacroImpl.expand(backendParam, defn)
defn.copy(body = body)
case x =>
abort(s"Unrecognized pattern $x")
}
}
case _ =>
abort("This annotation only works on `def`")
}
}
}
object MeasureMacroImpl {
def expand(nameExpr: Term.Arg, annotatedDef: Defn.Def): Term = {
val name: Term.Name = Term.Name(nameExpr.syntax)
annotatedDef match {
case q"..$_ def $methodName[..$tps](..$nonCurriedParams): $rtType = $expr" => {
rtType match {
case f: Future[Any] => q"""
val name = $name
println("before " + name)
val future: ${rtType} = ${expr}
future.map(result => {
println("after " + name)
result
})
"""
case _ => q"""
val name = $name
println("before " + name)
val result: ${rtType} = ${expr}
println("after " + name)
result
"""
}
}
case _ => abort("This annotation only works on `def`")
}
}
}
我这样使用注解:
@measure("A")
def test(x: String): String = x
@measure("B")
def testMultipleArg(x: Int, y: Int): Int = x + y
我想将它与这样的异步方法一起使用:
@measure("C")
def testAsync(x: String)(implicit ec: ExecutionContext) : Future[String] = {
Future(test(x))
}
但我收到以下错误:
exception during macro expansion:
scala.meta.internal.inline.AbortException: This annotation only works on `def`
我假设问题是 MeasureMacroImpl 匹配,但我不确定如何匹配多个参数组。你们能帮帮我吗?任何想法或示例代码将不胜感激。我对 scala 和 scala meta 很陌生,如果我问了一个微不足道的问题,我深表歉意。
您遇到错误,因为 MeasureMacroImpl
与柯里化参数不匹配。
匹配柯里化参数相当简单,只需使用
scala
case q"..$_ def $methodName[..$tps](...$nonCurriedParams): $rtType = $expr"
注意 ...$nonCurriedParams
而不是 ..$nonCurriedParams
我正在玩 scalameta,我想要一个通用的测量注释,它发送有关方法执行时间的测量值。
我用的是Qing Wei的缓存注解demo。 https://www.cakesolutions.net/teamblogs/scalameta-tut-cache
它适用于非异步方法,但由于 ExecutionContext 参数列表,我的属性与 return Future 的方法不匹配。
我的注释如下所示:
package measurements
import scala.concurrent.Future
import scala.meta._
class measure(name: String) extends scala.annotation.StaticAnnotation {
inline def apply(defn: Any): Any = meta {
defn match {
case defn: Defn.Def => {
this match {
case q"new $_($backendParam)" =>
val body: Term = MeasureMacroImpl.expand(backendParam, defn)
defn.copy(body = body)
case x =>
abort(s"Unrecognized pattern $x")
}
}
case _ =>
abort("This annotation only works on `def`")
}
}
}
object MeasureMacroImpl {
def expand(nameExpr: Term.Arg, annotatedDef: Defn.Def): Term = {
val name: Term.Name = Term.Name(nameExpr.syntax)
annotatedDef match {
case q"..$_ def $methodName[..$tps](..$nonCurriedParams): $rtType = $expr" => {
rtType match {
case f: Future[Any] => q"""
val name = $name
println("before " + name)
val future: ${rtType} = ${expr}
future.map(result => {
println("after " + name)
result
})
"""
case _ => q"""
val name = $name
println("before " + name)
val result: ${rtType} = ${expr}
println("after " + name)
result
"""
}
}
case _ => abort("This annotation only works on `def`")
}
}
}
我这样使用注解:
@measure("A")
def test(x: String): String = x
@measure("B")
def testMultipleArg(x: Int, y: Int): Int = x + y
我想将它与这样的异步方法一起使用:
@measure("C")
def testAsync(x: String)(implicit ec: ExecutionContext) : Future[String] = {
Future(test(x))
}
但我收到以下错误:
exception during macro expansion:
scala.meta.internal.inline.AbortException: This annotation only works on `def`
我假设问题是 MeasureMacroImpl 匹配,但我不确定如何匹配多个参数组。你们能帮帮我吗?任何想法或示例代码将不胜感激。我对 scala 和 scala meta 很陌生,如果我问了一个微不足道的问题,我深表歉意。
您遇到错误,因为 MeasureMacroImpl
与柯里化参数不匹配。
匹配柯里化参数相当简单,只需使用
scala
case q"..$_ def $methodName[..$tps](...$nonCurriedParams): $rtType = $expr"
注意 ...$nonCurriedParams
而不是 ..$nonCurriedParams