gpt4 book ai didi

scala - 宏注释的类型

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

如何获得宏注释的(“当前”)类型?

import scala.annotation.StaticAnnotation
import scala.reflect.macros._
import language.experimental.macros

class myself extends StaticAnnotation {
def macroTransform(annottees: Any*) = macro myselfMacro.impl
}
object myselfMacro {
def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
val a = annottees.head
println(s"static type = ${a.staticType}")
println(s"actual type = ${a.actualType}")
c.Expr[Any](Literal(Constant()))
}
}

测试:
@myself class Foo

输出:
static type = Nothing
actual type = null

我想要该类型的原因是我想将其用作类型参数,例如 Bar[Foo]
编辑 :

好的,所以我认为正确的方法是这样的:
def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
val v = annottees.head.asInstanceOf[ClassDef]
val tpe = v.tpe // <- tpe is null as the annotated type is not yet type checked!
val tpe2 = if (tpe == null)
c.typeCheck(v).tpe // <- fails with a compiler error (assertion failure)
else
tpe
println(s"Type of annottee: $tpe2")
???
}

但是 given this post by Eugene Burmako ,看起来像 it is currently not possible ...

最佳答案

当宏注释被扩展时,被注释者还没有为它创建符号(有时它有,但不是给定的)。因此,它不能被符号/类型引用,只能被树引用,例如Ident(TypeName("Foo")) .当然,c.typecheck 的结果会给你一些符号/类型,但它只能用于自省(introspection)目的,而不是作为引用点。

如果您避开卫生问题,这种方法应该可以正常工作。如果您的伴生对象定义了一个名为 Foo 的类/类型成员,然后 FooSerializer[Foo]将绑定(bind)到同伴的成员,而不是原始类。目前没有很好的处理方法(scalac 本身在为案例类生成应用/取消应用方法时必须解决这个问题,但你不想知道它是如何完成的)。我们计划为此提供一个解决方案,但我们只会在下个月开始研究它,所以它需要一段时间才能到达树干甚至天堂。

关于scala - 宏注释的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21044957/

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