gpt4 book ai didi

scala - 检索将分配给 Scala 宏调用的值的名称

转载 作者:行者123 更新时间:2023-12-01 14:03:09 25 4
gpt4 key购买 nike

我正在尝试编写一个宏来包装一个函数并从其调用将分配给的值中减去一个参数。

object TestMacros {
def foo(name: String): String = name.toUpper
def bar = macro barImpl
def barImpl(c: Context): c.Expr[String] = {
import c.universe._
//TODO extract value name (should be baz)
c.Expr[String](Apply(
Select(newTermName("TestMacros"), newTermName("foo")), // Probably wrong, just typed it quickly for demonstration purposes
List(Literal(Constant("test"))))) // Should replace test by value name
}
}

object TestUsage {
val baz = bar // should be BAZ
}

我不知道这是否足够清楚。我调查了 c.prefix 和 c.macroApplication 但没有成功。我使用的是没有 macro-paradise 编译器插件的 Scala 2.10.2。

最佳答案

这是很有可能的。我知道,因为我已经完成了something like it before .诀窍是在封闭树中搜索一个值,该值的右侧与宏应用程序的位置相同:

import scala.language.experimental.macros
import scala.reflect.macros.Context

object TestMacros {
def foo(name: String): String = name.toUpperCase

def bar = macro barImpl
def barImpl(c: Context): c.Expr[String] = {
import c.universe._

c.enclosingClass.collect {
case ValDef(_, name, _, rhs)
if rhs.pos == c.macroApplication.pos => c.literal(foo(name.decoded))
}.headOption.getOrElse(
c.abort(c.enclosingPosition, "Not a valid application.")
)
}
}

然后:

scala> object TestUsage { val baz = TestMacros.bar }
defined module TestUsage

scala> TestUsage.baz
res0: String = BAZ

scala> class TestClassUsage { val zab = TestMacros.bar }
defined class TestClassUsage

scala> (new TestClassUsage).zab
res1: String = ZAB

请注意,您可以在编译时应用 foo,因为您在编译时知道 val 的名称。当然,如果您希望它在运行时应用,那也是可能的。

关于scala - 检索将分配给 Scala 宏调用的值的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18450203/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com