동일한 모듈의 암시 적 구체화
Dec 15 2020
다음과 같은 매개 변수화 된 클래스가 있습니다.
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
그러나 문제는 단일 클래스를 별도의 모듈로 추출하는 것이 절대적으로 추하고 번거로워 보인다는 것입니다. 이를 방지 할 수있는 "잘 알려진 해결 방법"이 있습니까? 형태가없는 것이 도움이 될 수 있습니까?
UPD :
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)
답변
3 DmytroMitin Dec 15 2020 at 21:35
별도의 모듈로 추출 할 수는 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]}]"
}
}
추악하든 아니든 매크로 구현은 적용하기 전에 컴파일해야합니다.
이것은 Scala 3에서 개선되었습니다.
http://dotty.epfl.ch/docs/reference/metaprogramming/macros.html#defining-a-macro-and-using-it-in-a-single-project
Shapeless는 미리 정의 된 표준 매크로 집합을 숨길 뿐이며 사용자 고유의 매크로에는 도움이되지 않습니다.