2015-10-07 3 views
0

Исходя из следующей реализации макросов, которая работает как ожидалось, я хотел бы удалить жестко закодированную учетную запись и заменить ее переменной beeing, переданной как параметр типа T: c. WeakTypeTag для макроса вызывающим. Как изменить макрос, чтобы я мог передавать любой тип T?Тип передачи Параметр для подтверждения при реализации макроса scala

`

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

`

ответ

2

может быть, вы можете использовать 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 
    """ 
    } 
} 

--- использовать как этот

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

узел должен import Api –

+0

спасибо, что был подсказкой, которую я искал (как передать тип param eter для макроса. вот реализация, которая выполнила задание ' ' – Bate

0

Спасибо, что был намек я был ищу как ответ на мой вопрос stion:

Как передать параметр pass в конкретном параметре типа для реализации макроса?

Короткий ответ: Используйте quasiquote

См реализации ниже, сделал работу `

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

Смежные вопросы