在Scala中访问不同类的同名参数

Accessing parameters of the same name of different classes in Scala

我有一个非常具体的场景,其中我有一些不同的抽象 classes 有子案例 classes 可以有不同的参数,例如:

abstract class ball() {}

case class football(_name: String, _shape: String) extends ball

case class basketball(_name: String, _size: Int) extends ball

和不同的摘要class:

abstract class food() {}

case class vegetarian(_name: String, calories: Int) extends food

case class meat(_name: String, proteinCount: Int) extends food

现在,我面临的问题是我需要在不知道 class 是什么的情况下以某种方式提取所有这些名称,我只知道总是,每个 CLASS一个名为 _name 的参数。

假设我们有一个 object 以上 class 中的任何一个,我正在尝试这样做:

object.getClass.getDeclaredField("_name").get(this)

但我收到错误消息:

can not access a member of class package.food with modifiers "private"

我尝试将 val 和 var 放在 class 中的参数之前,但没有用。我还尝试在 get(this) 之前的一行中执行 "setAccessible(true)",这也无济于事。

显而易见的干净解决方案是让所有这些至少有一个共同特征 类:

trait HasName {
  def _name: String
}

然后你就可以安全地做 obj.asInstanceOf[HasName]._name。更好的是,如果您设法保留 objHasName 的静态信息,在这种情况下 obj._name 就足够了。

如果您做不到这些,反思是必经之路。您可以使用结构类型轻松完成此操作,在本例中:

obj.asInstanceOf[{ def _name: String }]._name

请注意,这将比上面的 HasName 解决方案慢,并且在编译时完全未检查。