【问题标题】:Scala dynamic instantiation with default arguments使用默认参数的 Scala 动态实例化
【发布时间】:2013-06-04 21:49:34
【问题描述】:

有没有办法动态实例化一个指定了一个或多个默认参数的 Scala 案例类?

我正在寻找与此等效的动态(基于反射):

case class Foo( name:String, age:Int = 21 )
val z = Foo("John") 

现在如果我尝试这个,我会得到一个异常:

val const = Class.forName("Foo").getConstructors()(0)
val args = Array("John").asInstanceOf[Array[AnyRef]]
const.newInstance(args:_*)

如果我在参数数组中添加年龄值,没问题。

【问题讨论】:

标签: scala dynamic reflection creation


【解决方案1】:

您可以在运行时获取默认参数作为对象的方法。

如果是构造函数参数 - 伴随对象方法(scala 2.9.3)。

$ echo 'class Test(t: Int = 666)' > test.scala
$ scalac -Xprint:typer test.scala
...
<synthetic> def init$default$1: Int @scala.annotation.unchecked.uncheckedVariance = 666

您不能依赖此方法的名称。 (scala 2.10.1):

scala> Test.$lessinit$greater$default$1
res0: Int = 666

don't know 如何获取构造函数的默认参数,但在case class 的情况下,您可以获得apply 方法的默认参数。见this answer

【讨论】:

  • @som-snytt:2.9.32.10.1 的名称不同,所以不要使用名称,而是使用defaultGetterName 生成。
  • @som-snytt:你的评论让我想创建方法`&lt;init&gt;`
【解决方案2】:

具有默认值的参数是编译时的事情。编译器将为缺少参数的调用提供默认值。反射没有这样的事情,更不用说java反射了,它根本不知道默认参数。

【讨论】:

  • 您可以在运行时获取默认值作为方法。
  • 怎么样?我(还)没有那个对象的实例——我正在实例化它。
  • @Greg 在这种情况下 - 伴生对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 2011-09-02
相关资源
最近更新 更多