简体   繁体   中英

Can Scala macros generate the methods and implictits in this situation?

I want to use scala macros to do some kind of code generation. In specific, I define some Event types and these events will be pushed to the same method (here workImpl ) and return a value of a specific type. The return type is not determined if I just call workImpl , because it handles different inputs and returns different results. But the map between input types and output types is determined . The goal is to make the return type available.

Scala macro is fantastic and maybe helps. I want to achieve auto code generation by add event return type annotation for each event type. The code that is supposed to be generated is code1 or code2 .

object A {
    private def workImpl(x: Any): Any = ???

    @anno(X_RET)
    case class X()

    @anno(Y_RET)
    case class Y()

    @anno(Z_RET)
    case class Z()

    // code1: auto generate work1 and the implicits
    def work1[T](x:T)(implicit ev: T=>M) = workImpl(x).asInstanceOf[M]
    implicit val X_TO_X_RET: X=>X_RET = null
    implicit val Y_TO_Y_RET: Y=>Y_RET = null
    implicit val Z_TO_Z_RET: Z=>Z_RET = null

    // code2: auto generate these methods
    def work2(x:X) = workImpl(x).asInstanceOf[X_RET]
    def work2(x:Y) = workImpl(x).asInstanceOf[Y_RET]
    def work2(x:Z) = workImpl(x).asInstanceOf[Z_RET]    
}

So, is this possible and how to achieve this? If it is not possible, any solution else?

I finally find a solution that works.

object A {
  private def workImpl(x: Any): Any = x match {
    case e: X => XRet(0)
    case e: Y => YRet(0)
    case e: Z => ZRet(0)
  }

  trait Event
  trait EventReturn[T] extends Event

  case class X() extends EventReturn[XRet]
  case class Y() extends EventReturn[YRet]
  case class Z() extends EventReturn[ZRet]

  case class XRet(x:Int)
  case class YRet(y:Int)
  case class ZRet(z:Int)

  def work3[T](x: EventReturn[T]): T = workImpl(x).asInstanceOf[T]

  def main(args: Array[String]): Unit = {
    work3(X()).x
    work3(Y()).y
    work3(Z()).z
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM