Scala动态实例化带有默认参数
Scala动态实例化带有默认参数
有没有一种方法可以动态实例化一个Scala case类,并指定一个或多个默认参数?
我正在寻找动态(基于反射)等效的方法:
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:_*)
如果在参数数组中添加age的值,就没有问题。
Scala动态实例化默认参数的问题是由于反射机制导致的。在编译时,编译器会为调用中缺少参数的情况下提供默认值。但是反射机制并不支持默认参数。可以通过运行时方法获取默认值。那么问题来了,如何在没有实例化对象的情况下获取默认值呢?在这种情况下,可以使用伴生对象。
伴生对象是指与类名相同且被定义在同一个源文件中的对象。在伴生对象中,可以定义一些与类相关的静态方法和成员变量。通过伴生对象,可以在没有实例化对象的情况下访问类的默认参数。
解决方法如下:
class MyClass(param1: Int = 0, param2: String = "default") { def myMethod(): Unit = { println(s"param1: $param1, param2: $param2") } } object MyClass { def getDefaultParam1: Int = new MyClass().param1 def getDefaultParam2: String = new MyClass().param2 } // 使用伴生对象获取默认参数 val defaultParam1 = MyClass.getDefaultParam1 val defaultParam2 = MyClass.getDefaultParam2 val myObject = new MyClass() myObject.myMethod()
在这个例子中,MyClass类有两个默认参数param1和param2。在伴生对象中,我们定义了两个方法getDefaultParam1和getDefaultParam2,分别返回默认参数param1和param2的值。通过调用这两个方法,我们可以在没有实例化对象的情况下获取默认参数的值。
最后,我们可以通过实例化MyClass类并调用其方法来验证获取的默认参数值是否正确。
Scala动态实例化带有默认参数的问题的出现是因为在运行时,可以将默认参数作为对象的方法来获取。在构造函数参数的情况下,可以使用伴生对象方法(scala 2.9.3)来获取默认参数。
$ echo 'class Test(t: Int = 666)' > test.scala $ scalac -Xprint:typer test.scala ...def init$default$1: Int .annotation.unchecked.uncheckedVariance = 666
但是不能依赖于该方法的名称(scala 2.10.1):
scala> Test.$lessinit$greater$default$1 res0: Int = 666
我不知道如何获取构造函数的默认参数,但是在case class的情况下,可以获取到apply方法的默认参数。参见这个答案。
-snytt: 在2.9.3和2.10.1中,名称是不同的,所以不能使用名称,而是使用defaultGetterName来生成它。
-snytt: 你的评论让我想创建一个方法`