【问题标题】:Scala 3 (Dotty) Pattern match a function with a macro quotationScala 3(Dotty)模式将函数与宏引用匹配
【发布时间】:2021-03-19 05:36:03
【问题描述】:

我正在尝试通过 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"

我想知道这是否可以使用引号以更简单的方式完成。

【问题讨论】:

    标签: scala macros scala-macros dotty scala-3


    【解决方案1】:

    我想定义就够了

    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 中测试。

    How to access parameter list of case class in a dotty macro

    你也可以试试

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

    【讨论】:

    • 感谢您的回答!第一个选项不起作用,因为它采用第一个字段并忽略f。第二个与我的解决方案大致相同,但我有点懒于表示整个树结构:)。我正在寻找的是类似于选项 2 的方法,但带有引号 '{...}.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 2013-09-04
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多