是否可以使用scala宏执行以下操作:
trait Cacheable {
def cache[T](genValue: => Future[T]): Future[T] = macro Cacheable.cacheImpl[T]
}
object Cacheable {
def cacheImpl[A: c.WeakTypeTag](c: Context)
(genValue: c.Expr[Future[A]]): c.Expr[Future[A]] = {
import c.universe._
reify {
genValue.splice
}
}
}
它不能在Cacheable trait中的宏函数调用中编译,并带有以下消息:
此行有多个标记 - 宏实现形状错误:必需: (c:scala.reflect.macros.Context)(genValue:c.Expr [=> scala.concurrent.Future [T]]):c .Expr [scala.concurrent.Future [T]]发现:(c: scala.reflect.macros.Context)(genValue:c.Expr [scala.concurrent.Future [A]]):c .Expr [scala.concurrent.Future [A]]参数genValue的类型不匹配:c.Expr [= > scala.concurrent.Future [T]]不符合c.Expr [scala.concurrent.Future [?A]] - 宏实现形状错误:必需:(c:scala.reflect.macros.Context)(genValue: c.Expr [=> scala.concurrent.Future [T]]):c .Expr [scala.concurrent.Future [T]] found:(c:scala.reflect.macros.Context)(genValue:c.Expr [scala.concurrent.Future [A]]):c .Expr [scala.concurrent.Future [A]]参数genValue的类型不匹配:c.Expr [=> scala.concurrent.Future [T]]不符合c.Expr [scala.concurrent.Future [?A]]
答案 0 :(得分:-1)
首先让你的签名正确:
import concurrent.Future
import language.experimental.macros
import reflect.macros.Context
trait Cacheable {
def cache[A](genValue: => Future[A]): Future[A] = macro Cacheable.cacheImpl[A]
}
object Cacheable {
def cacheImpl[A: c.WeakTypeTag](c: Context)
(genValue: c.Expr[Future[A]]): c.Expr[Future[A]] = ???
}
错误很明显:
<console>:12: error: macro implementation has wrong shape:
required: (c: scala.reflect.macros.Context)(genValue: c.Expr[=> scala.concurrent.Future[A]]): c.Expr[scala.concurrent.Future[A]]
found : (c: scala.reflect.macros.Context)(genValue: c.Expr[scala.concurrent.Future[A]]): c.Expr[scala.concurrent.Future[A]]
type mismatch for parameter genValue: c.Expr[=> scala.concurrent.Future[A]] does not conform to c.Expr[scala.concurrent.Future[?A]]
def cache[A](genValue: => Future[A]): Future[A] = macro Cacheable.cacheImpl[A]
^
您要求cache
方法中的call-by-name参数,但在宏实现方法中使用eager类型。
没有相应的类型c.Expr[=> Future[A]]
,我非常怀疑可以表达这种类型。因为宏将表达式转换为Future[A]
,如果要“按需”使用该表达式,则必须在宏中生成的AST中提供一种机制。由于您的返回类型为Future[A]
,而不是() => Future[A]
,因此我不知道您将如何在此处实现此目标,或者您究竟想要实现的目标。