scala:检索用于以可继承方式构造类实例的参数



在 scala 中,我遇到过一个基类/特征被很多子类扩展的情况。 我将通过获取类的名称和用于实例化类的参数来序列化子类的实例(以便稍后重建它)。 使用反射很容易获取类实例的名称,但我不确定如何获取实例的参数以一种不需要我在每个子类中编写代码的方式。 这也适用于按名称调用的参数。这似乎很棘手,因为每个子类可能具有完全不同的构造函数参数数量和类型:

abstract class Base {
  // ideally implements some way of finding out the arguments used to construct this object
  def getArgs = {...}
}
class ChildA() // args would be a 0-tuple
class ChildB(arg1: Int) // getArgs would be a 1-tuple of arg1
class ChildC(arg1: Double, arg2: Boolean) // args would be a 2-tuple of (arg1, arg2)
// etc... 

我想避免的是让每个类实现一个像"getArgs"这样的方法,并且只返回一个从构造函数复制参数的元组。 有什么办法可以做到这一点吗?

意识到另一种方法是使用某种拦截器来创建对象,但是我无法弄清楚如何在不必为每个子类编写样板代码的情况下做到这一点。

编辑:案例类方法很优雅,但在我的情况下不适合,因为我们必须能够允许具体的子类扩展其他具体的子类。

如果您

的目标是避免在每个子类中编写代码来捕获参数,并且所有子类都位于平面层次结构中,直接从Base继承而不是彼此继承,则应考虑将它们声明为 case class es。然后它们会自动扩展Product您可以使用和productIterator例如将所有参数保存到Array[Any](我正在使用Array因为这是稍后反射性调用这些类的构造函数时所需要的):

scala> def toArray(p: Product) = p.productIterator.toArray
toArray: (p: Product)Array[Any]
scala> case class ChildA()
defined class ChildA
scala> toArray(ChildA())
res0: Array[Any] = Array()
scala> case class ChildB(arg1: Int)
defined class ChildB
scala> toArray(ChildB(42))
res1: Array[Any] = Array(42)

如果希望toArray只接受 Base 的子类,则将其参数声明为 Product with Base

相关内容

  • 没有找到相关文章

最新更新