Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何识别Scala宏中的匿名类?_Scala_Reflection_Scala Macros - Fatal编程技术网

如何识别Scala宏中的匿名类?

如何识别Scala宏中的匿名类?,scala,reflection,scala-macros,Scala,Reflection,Scala Macros,我有一个枚举类成员的宏。我想扩展宏,使其递归工作,方法是将内部枚举到以下形式的任何类成员中: object obj { var name = "value" var nested = new { var x = 0 } } 在转换到宏之前我使用的运行时反射中,对我有效的对应测试是symbol.info.wilded=:=typeOf[AnyRef],但是这不能用于宏,因为在这种情况下,类型不是AnyRef,

我有一个枚举类成员的宏。我想扩展宏,使其递归工作,方法是将内部枚举到以下形式的任何类成员中:

    object obj {
      var name = "value"
      var nested = new {
        var x = 0
      }
    }
在转换到宏之前我使用的运行时反射中,对我有效的对应测试是
symbol.info.wilded=:=typeOf[AnyRef]
,但是这不能用于宏,因为在这种情况下,类型不是AnyRef,而是它的子类(优化)

当我将类型打印到控制台时,我得到例如:

AnyRef{def x:Int;def x_=(x$1:Int):Unit}

当我列出所有基类时,我得到:

列表(,类对象,类任意)

我不能使用测试

val fName=f.name.decodedName.toString

如果(f.info.wilded=:=typeOf[AnyRef]){//在宏中尝试用按类型匹配的模式替换
if-else

val anyRefType = typeOf[AnyRef]

f.info match {
  case NullaryMethodType(RefinedType(List(`anyRefType`), _)) =>
    q"$fName -> listMembersNested(t.$f)"
  case _ =>
    q"$fName -> t.$f"
}

在宏中,尝试用按类型匹配的模式替换
if-else

val anyRefType = typeOf[AnyRef]

f.info match {
  case NullaryMethodType(RefinedType(List(`anyRefType`), _)) =>
    q"$fName -> listMembersNested(t.$f)"
  case _ =>
    q"$fName -> t.$f"
}

如果我调用运行时反射版本
listMembersNested_A(obj)
,那么它将生成
List((嵌套,pckg.App$obj$$anon$1@7ae42ce3),(名称、值))
即在
if-else
中,分支
字段.get
同时被选中,分支
listMembersNested\u A(字段.get)
从未被选中。这是预期的行为吗?并且您的宏版本
listMembers(obj)
(我定义了
def listMembers[O](t:O)(隐式lmn:ListMembersTested[O]):Seq[(String,Any)]=lmn.listMembers(t)
)会生成
Seq(“name”。$减$大(t.name),“嵌套”。$减$大(t.nested))
。所以我看不出运行时反射版本和宏版本的工作方式有什么区别。“如果我调用运行时反射版本”,这真的很奇怪。在我的项目中调试函数时,它为我进入
ListMembersTested\u A
递归,生成的结果是“List((嵌套,List((x,0)),(name,value))”然后。当我在Scastie中尝试这一点时,我得到了与您相同的结果。这是Scala 2.12.12。只有当
obj
被定义为函数中的局部变量时,我才得到我描述的行为。当它是另一个对象/类的成员时,我得到了您描述的行为。当我在ScalaTest中调试它时,它是一个局部变量。相关问题:如果我调用运行时反射版本
listMembersNested_A(obj)
,那么它将生成
List((嵌套,pckg.App$obj$$anon$1@7ae42ce3),(名称、值))
即在
if-else
中,分支
字段.get
同时被选中,分支
listMembersNested\u A(字段.get)
从未被选中。这是预期的行为吗?并且您的宏版本
listMembers(obj)
(我定义了
def listMembers[O](t:O)(隐式lmn:ListMembersTested[O]):Seq[(String,Any)]=lmn.listMembers(t)
)会生成
Seq(“name”。$减$大(t.name),“嵌套”。$减$大(t.nested))
。所以我看不出运行时反射版本和宏版本的工作方式有什么区别。“如果我调用运行时反射版本”,这真的很奇怪。在我的项目中调试函数时,它为我进入
ListMembersTested\u A
递归,生成的结果是“List((嵌套,List((x,0)),(name,value))”然后。当我在Scastie中尝试这一点时,我得到了与您相同的结果。这是Scala 2.12.12。只有当
obj
被定义为函数中的局部变量时,我才得到我描述的行为。当它是另一个对象/类的成员时,我得到了您描述的行为。当我在ScalaTest中调试它时,它是一个对我来说是局部变量。连接问题:很好。这真的很有效。在阅读了
RefinedType
ScalaDoc之后,我认为甚至可以进行更具体的匹配
NullaryMethodType(RefinedType(List(AnyRef))
,但不知何故似乎不再匹配。我现在明白了。我需要与[AnyRef]的
Types进行匹配
,不是简单的
AnyRef
@Suma如果更方便的话,你也可以匹配
f.info.resultType match{case-definedtype(List(`anyRefType`),_)=>…
@Suma很棒。这真的很有效。在阅读
definedtype
ScalaDoc I之后,尽管更具体的匹配是
NullaryMethodType(ref(List(AnyRef),)
是可以制作的,但不知怎么的,它似乎不再匹配了。我现在明白了。我需要匹配[AnyRef]
类型,而不是简单的
AnyRef
@Suma,如果更方便的话,你也可以匹配
f.info.resultType match{case-definedtype(List(`anyRefType`),_)=>…
@Suma
val anyRefType = typeOf[AnyRef]

f.info match {
  case NullaryMethodType(RefinedType(List(`anyRefType`), _)) =>
    q"$fName -> listMembersNested(t.$f)"
  case _ =>
    q"$fName -> t.$f"
}