scala - scala 隐式宏应该返回什么来告诉编译器 "forget my result, continue your search"

标签 scala implicit scala-macros

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

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。 宏应该返回什么来告诉编译器“忘记我的结果,继续你的隐式搜索,就好像我不存在一样”?

目前我正在返回一个空 block (q""),这并不理想,因为当将所述隐式用作中间规则时,编译器会具体化一个 null。例如,在下一行中,当宏返回空 (q"") 时,helper 参数设置为 null。

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

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

最佳答案

你没有让你的宏具体化类型类Helper whitebox。

Normally implicit macros should be whitebox.

If a blackbox macro (even implicit blackbox macro) throws an exception then it will be a compile error during compilation of main code. If a whitebox implicit macro throws an exception then during compilation of main code the implicit will be silently removed from candidates.

Implicit macro. Default implicit value. How?

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

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

关于scala - scala 隐式宏应该返回什么来告诉编译器 "forget my result, continue your search",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64538997/

相关文章:

scala - Scala 中用于具有继承返回类型的集合的最小框架

Scala 不确定性/缓存类?

scala - Scala 文档示例中的 "macro implementation reference has wrong shape"

scala - 简单的scala宏

scala - 使用宏转换树后重新建立类型一致性的最佳方法是什么

java - 使用 MongoDB/Morphia(Scala 或 Java)将 LatLon 类存储为 GeoJSON

multithreading - 在 S3 存储桶之间并行移动文件

scala - 您可以直接将非隐式 val 作为参数传递给需要隐式的函数吗?

string - Swift - 可选字符串与隐式解包可选字符串

function - 为什么传递给函数的所有数据都是 "explicitly passed"?