【问题标题】:Passing type Parameter to reify while implementing a scala macro在实现 scala 宏时传递类型参数来具体化
【发布时间】:2015-10-12 14:41:23
【问题描述】:

从以下按预期工作的宏实现开始,我想删除硬编码的 Account 并将其替换为由调用者作为类型参数 T:c.WeakTypeTag 传递给宏的变量。 应该如何修改宏以便我可以传递任何类型的 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
 }
}

`

【问题讨论】:

    标签: scala scala-macros


    【解决方案1】:

    也许你可以使用准引号

    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
        """
      }
    }
    

    ---这样使用

    object ReifyUsing extends App {
      import macross.Reify
      import macross.Api
      println(Reify.apply[String]("String").t)
    }
    

    【讨论】:

    • 谢谢你,这是我正在寻找的提示(如何将类型参数传递给宏。这是完成这项工作的实现` `
    【解决方案2】:

    谢谢你,这是我正在寻找的作为我问题答案的提示:

    如何将特定类型参数的参数传递给宏的实现?

    简答:使用准引号

    查看下面的实现 `

     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
    """
     }
    }
    

    ` 我使用这样的宏:

    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") } }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多