scala 同一模块中的隐式物化

fd3cxomn  于 2022-11-09  发布在  Scala
关注(0)|答案(1)|浏览(182)

我有一个参数化类,比如

class Test[T]{
    //...
}

object Test{
    implicit def materializeTest[T]: Test[T] = macro impl[T]

    def impl[T: c.WeakTypeTag](c: blackbox.Context) = //...
}

如果使用同一模块中的物化隐式,则会抛出错误:

macro implementation not found

但问题是,将单个类提取到单独的模块中看起来非常难看和笨拙。也许有一些“众所周知的解决办法”可以避免这种情况?也许无形造型在这里会有帮助?
更新:

scalaVersion in ThisBuild := "2.13.2"

以下是我的最小示例:

import scala.language.experimental.macros
import scala.reflect.macros.blackbox

object Main {
  sealed trait Adt
  case object Adt1 extends Adt
  case object Adt2 extends Adt

  trait Test[Adtt <: Adt] {
    def restrict(restrictions: List[Int]): List[Int]
  }

  object Test {
    def apply[Adtt <: Adt](implicit ev: Test[Adtt]): Test[Adtt] = ev

    implicit def implicitMaterializer[
        Adtt <: Adt
    ]: Test[Adtt] = macro impl[Adtt]

    def impl[Adtt <: Adt: c.WeakTypeTag](
        c: blackbox.Context
    ): c.Expr[Test[Adtt]] = {

      import c.universe._
      c.Expr[Test[Adtt]](q"""???""")
    }
  }

  def main(args: Array[String]): Unit = {
    Test[Adt1.type].restrict(List(1, 2, 3))
  }
}

这会导致以下错误:

[error] Main.scala:32:9: macro implementation not found: implicitMaterializer
[error] (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)
mwg9r5ms

mwg9r5ms1#

您可以解压到单独的模块,而不是Test,而是TestMacro

核心

import scala.language.experimental.macros

class Test[T]

object Test {
  implicit def materializeTest[T]: Test[T] = macro TestMacro.impl[T]
}

implicitly[Test[Int]] // compiles
  • 宏指令**
import scala.reflect.macros.blackbox

object TestMacro {
  def impl[T: c.WeakTypeTag](c: blackbox.Context) = {
    import c.universe._
    q"new Test[${weakTypeOf[T]}]"
  }
}

不管是否难看,但宏实现必须在应用之前编译(但Is there any trick to use macros in the same file they are defined?除外)。
这在Scala 3中得到了改进
Http://dotty.epfl.ch/docs/reference/metaprogramming/macros.html#defining-a-macro-and-using-it-in-a-single-project
Shapless只是隐藏了一些预定义的标准宏集,它对您自己的宏无助。

相关问题