c.inferImplicitValue
推断出调用网站范围中的隐含值。是否可以使用c.prefix
范围来推断隐含?
这不是有效的代码,但表达了我的需求:
c.prefix.inferImplicitValue
我目前正在为此目的使用一个天真的实现[1],但它有一些限制,例如不从def
推断隐含值并检测重复/模糊隐含值。
答案 0 :(得分:6)
只需生成一个具有适当(本地)导入的块,然后调用implicitly
即可:
q"""{import ${c.prefix}._; _root_.scala.Predef.implicitly[$T] }
其中T
是Type
的实例,表示要查找的隐式值的类型。
要检查隐式查找是否实际成功,您可以使用Context.typeCheck
调用silent=true
并检查结果树是否为空。
作为示例,这里是一个示例,如果在目标对象的成员中找不到隐式,则实现infer
方法返回None
,否则将结果包装在{{1 }}
Some
让我们测试一下:
import scala.reflect.macros.Context
import scala.language.experimental.macros
def inferImplicitInPrefixContext[T:c.WeakTypeTag](c: Context): c.Tree = {
import c.universe._
val T = weakTypeOf[T]
c.typeCheck(
q"""{
import ${c.prefix}._
_root_.scala.Predef.implicitly[$T]
}""",
silent = true
)
}
def infer_impl[T:c.WeakTypeTag](c: Context): c.Expr[Option[T]] = {
import c.universe._
c.Expr[Option[T]](
inferImplicitInPrefixContext[T](c) match {
case EmptyTree => q"_root_.scala.None"
case tree => q"_root_.scala.Some($tree)"
}
)
}
trait InferOp {
def infer[T]: Option[T] = macro infer_impl[T]
}