如何将类型编程与Scala宏结合使用
发布时间:2020-12-16 10:02:57 所属栏目:安全 来源:网络整理
导读:我想使用一个使用“type”关键字定义的类型的宏.我该如何参考? 我的起始代码是 import scala.reflect.macros.Contextimport scala.language.experimental.macrostrait Demo6 { type T def add(param: Any): T = macro Demo6.addImpl[T] def fullAdd(param:
我想使用一个使用“type”关键字定义的类型的宏.我该如何参考?
我的起始代码是 import scala.reflect.macros.Context import scala.language.experimental.macros trait Demo6 { type T def add(param: Any): T = macro Demo6.addImpl[T] def fullAdd(param: Any,toStringBasedOnAST: String): T = { doesSomeThing_and_returnsSomething_OfTypeT } def doesSomeThing_and_returnsSomething_OfTypeT: T //just to allow compilation } object Demo6 { def addImpl[T: c.WeakTypeTag](c: Context)(param: c.Expr[Any]): c.Expr[T] = { import c.universe._ reify { (c.Expr[Demo6](c.prefix.tree)).splice.fullAdd(param.splice,c.literal(show(param.tree)).splice) } // ^ - type mismatch; found : org.autotdd.scalamacros.Demo6#T // required: T } } 我在示例中标记了编译器错误.很明显发生了什么:关键字定义的类型T与我传入的类型T不同. 我尝试过的事情 解决方法
您的代码几乎是正确的,只需更改Expr的类型参数:
val expr = reify { ... } c.Expr[T](expr.tree) 没有reify你应该返回: c.Expr[T](Apply(Select(c.prefix.tree,newTermName("fullAdd")),List(param.tree,Literal(Constant(show(param.tree)))))) reify创建相同但具有错误的类型参数. 有关showRaw的使用,请参阅this answer. 在这种情况下: scala> import reflect.runtime.universe._ import reflect.runtime.universe._ scala> { | object Demo { def fullAdd(param1: Any,param2: String): String = "result" } | showRaw{ reify { Demo.fullAdd("param1","param2") } } | } res0: String = Expr(Apply(Select(Ident(newTermName("Demo")),List(Literal(Constant("param1")),Literal(Constant("param2"))))) 用c.prefix.tree替换Ident(newTermName(“Demo”)),用param.tree替换Literal(常量(“param1”))和用show(param.tree)替换“param2”,你将得到你的结果. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |