【问题标题】:Scala reflection: get all constructor arguments of a specific typeScala反射:获取特定类型的所有构造函数参数
【发布时间】:2021-05-13 13:30:18
【问题描述】:

我想创建一个通用方法def getOptionalArgs[T](): List[String],这样当传递一个类型时,它会返回该类型的所有参数列表,这些参数是Option[_]

例如我有一个case class Foo(bar: String, baz: Option[String])。在这种情况下,getOptionalArgs[Foo]() 将返回 List("baz")

我一直在搞乱反射库,我想我已经接近了:

import scala.reflect.runtime.{universe, universe => ru}

def getOptionalArgs[T]() = {
 val constructor = ru.typeOf[T].decl(ru.termNames.CONSTRUCTOR).asMethod
 ...
}

但我无法弄清楚如何映射/过滤反射的构造函数参数。这里缺少什么?

更新

constructor.paramLists.head.map(t => (t.name.toString, t.info)) 将返回 List[(String, reflect.runtime.universe.Type)] = List((bar,Int), (baz,Option[Int]))。所以它非常接近。现在我必须弄清楚如何测试Type 之间的相等性,不,equals 似乎不起作用。

【问题讨论】:

  • 请问,你为什么需要这个?您确定运行时反射是解决元问题的最佳答案吗?
  • 它...复杂。我正在使用 Dataset API 和许多案例类编写一个 spark 应用程序。我需要能够根据所述类的类型签名对数据构建任意过滤器。还有其他实现相同结果的方法,但并非没有大量开销。
  • 哦,好吧,尽管如此,Spark 已经是一堆低效且不安全的运行时反射。祝你好运。

标签: scala reflection scala-reflect


【解决方案1】:

解决办法是:

val constructor = ru.typeOf[I].decl(ru.termNames.CONSTRUCTOR).asMethod
val notOptionalColNames = constructor.paramLists.head
      .map(t => (t.name.toString, t.info))
      .filter(t => !(t._2 <:< typeTag[Option[_]].tpe)).map(_._1)

【讨论】:

    猜你喜欢
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2017-09-14
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    相关资源
    最近更新 更多