一个scala隐式宏应该返回什么来告诉编译器“忘记我的结果,继续搜索”

问题描述

我有一个带有贪婪签名的隐式宏

implicit def materializeHelper[C <: Any]: Helper[C] = macro materializeHelperImpl[C]

def materializeHelperImpl[C <: Any: ctx.WeakTypeTag](ctx: blackBox.Context): ctx.Expr[Helper[C]] = ???

根据它的签名,它将为任何C体现一个Helper[C]。但是,身体更具挑剔性。它仅接受C个密封特征。 宏应该返回什么来告诉编译器“忘记我的结果,继续进行隐式搜索,就像我不存在一样?”

当前,我正在返回一个空块(q""),这是不理想的,因为当所述隐式用作中间规则时,编译器会实现null。例如,在下面的行中,当宏返回空(helper)时,q""参数设置为null。

implicit def parser[C <: Any](implicit helper: Helper[C]): Parser[C] = new Parser[C](helper)

我的目的是,在C不是密封特征的情况下,编译器将丢弃前面提到的两个隐式值,并继续搜索一个更具体的隐式值。

解决方法

您没有将宏实现类型类Helper设置为白盒。

通常隐式宏应该是白盒。

如果黑盒宏(甚至是隐式黑盒宏)抛出异常 那么它将在编译主代码时出现编译错误。如果一个 whitebox隐式宏会在编译过程中引发异常 主代码中的隐式代码将从候选者中静默删除。

Implicit macro. Default implicit value. How?

https://docs.scala-lang.org/overviews/macros/blackbox-whitebox.html

使用自定义错误消息调用c.abort更为习惯。抛出异常,调用c.error,然后返回EmptyTree(在这种情况下,只是不进行类型检查)也是可能的,尽管它们看起来不那么习惯(最好有清晰的编译错误消息)。 / p>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...