我有一个功能
def grammar(block: => Any): Grammar = macro grammarImpl
使用宏实现
def grammarImpl(c: Context)(block: c.Tree): c.Expr[Grammar] =
{
q"null"
}
但我收到错误,输入不匹配;发现:c.universe.Literal required:c.Expr [Grammar](扩展为)c.universe.Expr [语法]
更换q" null"与c.literalNull然而编译好,我使用错误的quasiquote得到Null文字?
(Scala 2.11.6)
附带问题:我正在使用block:c.Tree,当我真的想要使用c.Expr [=>任何]。是否可以指定c.Expr [=>任何]类型?
答案 0 :(得分:2)
你需要做
def grammarImpl(c: Context)(block: c.Tree): c.Expr[Grammar] =
c.Expr[Grammar] {
q"null"
}
但是自scala 2.11(以下读取点9)以来,这已被弃用。
只需将返回类型更改为c.Tree
即可完成:
def grammarImpl(c: Context)(block: c.Tree): c.Tree = q"null"
这是scala 2.11中引入的更改,您可以阅读它here:
8)对宏实现签名的宽松要求。随着quasiquotes的出现,reify正在迅速成长,因为过于笨重和不灵活。要认识到我们现在允许两个参数和返回类型的宏实现都是
c.Tree
类型而不是c.Expr [Something]。不再需要编写大型签名,然后花费时间和代码行来尝试将宏实现与这些类型对齐。只需将树木带回来并将树木归还 - 样板就不见了。9)宏定义类型的推断正在逐步取消。鉴于新的事物方案,宏实现可以返回
c.Tree
而不是c.Expr[Something]
,因此不再可能从宏impl的返回类型中稳健地推断宏defs的返回类型(如果宏impl返回{ {1}},然后该树的类型是什么?)。因此,我们正逐步取消这种语言机制。宏impls返回c.Tree
仍可用于推断其宏defs的返回类型,但这将产生弃用警告,而尝试使用返回c.Expr[T]
的宏impl来推断a的返回类型宏def将导致编译错误。