scala 隐式宏应该 return 告诉编译器什么 "forget my result, continue your search"
what should a scala implicit macro have to return to tell the compiler "forget my result, continue your search"
我有一个带有贪婪签名的隐式宏
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]
。但是 body 更挑剔。它只接受 C
s 这是密封的特征。
宏 return 应该如何告诉编译器“忘记我的结果,继续你的隐式搜索,就好像我不存在一样”?
目前我正在 return 创建一个空块 (q""
),这并不理想,因为当将所述隐式用作中间规则时,编译器会实现 null
。例如,在下一行中,当宏 return 为空 (q""
).
时,helper
参数设置为 null
implicit def parser[C <: Any](implicit helper: Helper[C]): Parser[C] = new Parser[C](helper)
我的意图是,在 C
不是密封特征的情况下,编译器会丢弃前面提到的隐式并继续搜索另一个更具体的隐式值。
你没有让你的宏具体化类型 class 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.
https://docs.scala-lang.org/overviews/macros/blackbox-whitebox.html
使用自定义错误消息调用 c.abort
更为惯用。抛出异常,调用 c.error
,返回 EmptyTree
(在这种情况下它只是不进行类型检查)也是可能的,尽管它们看起来不那么惯用(最好有明确的编译错误消息)。
我有一个带有贪婪签名的隐式宏
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]
。但是 body 更挑剔。它只接受 C
s 这是密封的特征。
宏 return 应该如何告诉编译器“忘记我的结果,继续你的隐式搜索,就好像我不存在一样”?
目前我正在 return 创建一个空块 (q""
),这并不理想,因为当将所述隐式用作中间规则时,编译器会实现 null
。例如,在下一行中,当宏 return 为空 (q""
).
helper
参数设置为 null
implicit def parser[C <: Any](implicit helper: Helper[C]): Parser[C] = new Parser[C](helper)
我的意图是,在 C
不是密封特征的情况下,编译器会丢弃前面提到的隐式并继续搜索另一个更具体的隐式值。
你没有让你的宏具体化类型 class 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.
https://docs.scala-lang.org/overviews/macros/blackbox-whitebox.html
使用自定义错误消息调用 c.abort
更为惯用。抛出异常,调用 c.error
,返回 EmptyTree
(在这种情况下它只是不进行类型检查)也是可能的,尽管它们看起来不那么惯用(最好有明确的编译错误消息)。