[英]Passing type Parameter to reify while implementing a scala macro
Going from the following macro implementation, which is working as expected, i would like to remove the hard coded Account and replace it with a variable beeing passed as type parameter T:c.WeakTypeTag to the macro by the caller. 从下面的按预期方式运行的宏实现中,我想删除硬编码的Account并将其替换为由调用者作为类型参数T:c.WeakTypeTag传递给宏的变量beeing。 how should the macro be modified so that i can pass any type T? 应该如何修改宏,以便我可以传递任何类型T?
` `
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
import com.xy.iws.model.Model._
import com.xy.iws.repo.dao.DAO._
import com.xy.iws.service.run
import com.xy.iws.service.Api
import com.xy.iws.service.Request._
object makeService {
def make[T]:Api[Account] = macro makeImpl[T]
def makeImpl[T:c.WeakTypeTag](c: Context): c.Expr[Api[Account]] = c.universe.reify {
//val source = c.weakTypeOf[T]
import com.xy.iws.service.Request._
implicit val api = new Api[Account] {
def create():Int = {run.runG[Int](Create[Account])}
def all(): List[Account] = run.runG[List[Account]](new FindAll[Account])
def insert(model: List[Account]) = run.runG[Int](new Insert[Account](model))
def findSome(id: String): List[Account] = run.runG[List[Account]](new FindSome[Account](id))
def find(id: String): List[Account] = run.runG[List[Account]](new Find[Account](id))
def update(item: Account): List[Account] = {
val i = run.runG[List[Account]](new Find[Account](item.id))
if (i.size > 0) {
val updateAccount = run.runG[Int](new Update[Account](item.id, item.name))
}else {
insert(List(item))
}
run.runG[List[Account]](new FindAll[Account])
}
def delete(id: String): List[Account] = {
run.runG[Int](new Delete[Account](id))
run.runG[List[Account]](new FindAll[Account])
}
}
api
}
}
` `
maybe you can use quasiquotes 也许你可以使用准引用
abstract class Api[T] {
def a: Int
def b: Int
def t: List[T]
}
object Reify {
def apply[T](initValue: T): Api[T] = macro impl[T]
def impl[T: c.WeakTypeTag](c: Context)(initValue: c.Expr[T]): c.Tree = {
import c.universe._
val t = c.weakTypeOf[T].typeSymbol.name.toTypeName
q"""
val api = new Api[$t] {
def a = 1
def b = 2
override def t= List(${initValue})
}
api
"""
}
}
---use like this ---这样使用
object ReifyUsing extends App {
import macross.Reify
import macross.Api
println(Reify.apply[String]("String").t)
}
Thank you that was the hint i was looking for as answer to my question: 谢谢,这是我一直在寻找的答案,以解决我的问题:
How to pass pass parameter in particular type parameter to the implementation of a macro? 如何将传递参数(特别是类型参数)传递给宏的实现?
Short answer: Use quasiquote 简短答案:使用准引用
See the implementation below that did the job ` 请参阅以下完成工作的实施`
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
import com.xy.iws.model.Model._
import com.xy.iws.repo.dao.DAO._
object makeService {
import com.xy.iws.service.Api
import com.xy.iws.service.Request
def make[T]:Api[T] = macro makeImpl[T]
def makeImpl[T:c.WeakTypeTag](c: Context): c.Tree = {
import c.universe._
val t = c.weakTypeOf[T].typeSymbol.name.toTypeName
q"""
implicit val api = new Api[$t] {
override def create():Int = {run.runG[Int](Create[$t])}
override def all(): List[$t] = run.runG[List[$t]](new FindAll[$t])
override def insert(model: List[$t]) = run.runG[Int](new Insert[$t](model))
override def findSome(id: String): List[$t] = run.runG[List[$t]](new FindSome[$t](id))
override def find(id: String): List[$t] = run.runG[List[$t]](new Find[$t](id))
override def update(item: $t): List[$t] = {
val i = run.runG[List[$t]](new Find[$t](item.id))
if (i.size > 0) {
run.runG[Int](new Update[$t](item.id, item.name))
}else {
insert(List(item))
}
run.runG[List[$t]](new FindAll[$t])
}
override def delete(id: String): List[$t] = {
run.runG[Int](new Delete[$t](id))
run.runG[List[$t]](new FindAll[$t])
}
}
api
"""
}
}
` and i use the macro like this: `并且我使用这样的宏:
object Main { def main(args: Array[String]) {
import com.xy.iws.service.Api println(makeService.make[Account].all +" account objects") println(makeService.make[Article].all +" article objects") println(makeService.make[Supplier].all +" supplier objects") } }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.