泛型类的 scala 宏泛型字段不适用类泛型类型参数

标签 scala generics macros scala-macros

通用案例类

case class GroupResult[T](
  group: String,
  reduction: Seq[T]
)

宏方法
 def foo[T] = macro fooImpl[T]

 def fooImpl[T: c.WeakTypeTag](c: Context) = {
    import c.universe._
    val tpe = weakTypeOf[T]
     tpe.declarations.collect {
      case m: MethodSymbol if m.isCaseAccessor => println(m.returnType)
    }
    c.literalUnit
  }

当我调用 foo[GroupResult[Int]]
输出是
String
Seq[T]

T 不适用?我怎样才能获得申请的Seq[Int] ?

最佳答案

您可以使用 typeSignatureIn获取给定方法的类型签名 GroupResult[Int] :

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

case class GroupResult[T](group: String, reduction: Seq[T])

def foo[T] = macro fooImpl[T]

def fooImpl[T: c.WeakTypeTag](c: Context) = {
  import c.universe._

  val tpe = weakTypeOf[T]

  tpe.declarations.collect {
    case m: MethodSymbol if m.isCaseAccessor => println(m.typeSignatureIn(tpe))
  }

  c.literalUnit
}

进而:
scala> foo[GroupResult[Int]]
=> String
=> Seq[Int]

所以我们更接近了,但现在我们得到了访问器的“类型”,而不是它们的返回类型。如果我们想要返回类型,我们可以使用 NullaryMethodType提取器:
def foo[T] = macro fooImpl[T]

def fooImpl[T: c.WeakTypeTag](c: Context) = {
  import c.universe._

  val tpe = weakTypeOf[T]

  tpe.declarations.collect {
    case m: MethodSymbol if m.isCaseAccessor => m.typeSignatureIn(tpe) match {
      case NullaryMethodType(returnType) => println(returnType)
    }
  }

  c.literalUnit
}

进而:
scala> foo[GroupResult[Int]]
String
Seq[Int]

我们已经完成了。

关于泛型类的 scala 宏泛型字段不适用类泛型类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25013047/

相关文章:

javascript - 扩展挑战 : preprocessor function macros and class-like oop

scala - 如何评估 Scala 宏中的表达式?

scala - Intellij Idea无法识别Scala类中的可变字段,出现 'Reassignment to val'错误

xml - 阻止 Scala 解析 XML

scala - 构建 Spark 1.3.0 时出错 - 未解析的依赖项路径

go - Go 1.18 中的 "any"类型是什么?

parsing - Play 2.0 框架,使用带有经过身份验证的请求的 BodyParser

generics - 未实现特征时返回泛型

c# - 泛型<T>怎么投?

c++ - 使一堆 C++ 类具有可比性,同时避免代码重复