Scala 3 (Dotty) 패턴은 매크로 인용이있는 함수와 일치합니다.
Dec 08 2020
Scala 3.0.0-M2에서 매크로를 통해 함수 이름을 얻으려고합니다. TreeAccumulator
import scala.quoted._
inline def getName[T](inline f: T => Any): String = ${getNameImpl('f)}
def getNameImpl[T](f: Expr[T => Any])(using Quotes): Expr[String] = {
import quotes.reflect._
val acc = new TreeAccumulator[String] {
def foldTree(names: String, tree: Tree)(owner: Symbol): String = tree match {
case Select(_, name) => name
case _ => foldOverTree(names, tree)(owner)
}
}
val fieldName = acc.foldTree(null, Term.of(f))(Symbol.spliceOwner)
Expr(fieldName)
}
이 코드를 호출하면 함수 이름이 생성됩니다.
case class B(field1: String)
println(getName[B](_.field1)) // "field1"
따옴표를 사용하여 더 쉽게 할 수 있는지 궁금합니다.
답변
2 DmytroMitin Dec 13 2020 at 14:44
정의하기에 충분하다고 생각합니다
def getNameImpl[T: Type](f: Expr[T => Any])(using Quotes): Expr[String] = {
import quotes.reflect._
Expr(TypeTree.of[T].symbol.caseFields.head.name)
}
사실 저는 f
.
테스트 :
println(getName[B](_.field1)) // "field1"
3.0.0-M3-bin-20201211-dbc1186-NIGHTLY에서 테스트되었습니다.
dotty 매크로에서 케이스 클래스의 매개 변수 목록에 액세스하는 방법
또는 시도해 볼 수 있습니다.
def getNameImpl[T](f: Expr[T => Any])(using Quotes): Expr[String] = {
import quotes.reflect._
val fieldName = f.asTerm match {
case Inlined(
_,
List(),
Block(
List(DefDef(
_,
List(),
List(List(ValDef(_, _, _))),
_,
Some(Select(Ident(_), fn))
)),
Closure(_, _)
)
) => fn
}
Expr(fieldName)
}