将强制和任意可选构造函数参数与Groovy相结合

时间:2017-06-22 21:06:47

标签: groovy jvm kotlin

我试图确定,纯粹是出于兴趣,是否有可能通过使用命名和默认构造函数参数完全消除在Groovy中使用Builder模式的需要;也就是说,仅使用内置语言功能来解决伸缩构造函数问题。

例如,在Kotlin中,可以执行以下操作:

data class Thing(val mandatory1: Int,
             val mandatory2: Int,
             val optional1: Int = 100,
             val optional2: Int = 200,
             val nullable: Int? = null)

   fun main(args: Array<String>) {

        val things = listOf(
                Thing(1, 2),
                Thing(1, 2, 3),
                Thing(1, 2, 3, 4),
                Thing(1, 2, 3, 4, 5),
                Thing(1, 2, optional2 = 4),
                Thing(1, 2, optional1 = 4),
                Thing(1, 2, nullable = 4),
                Thing(  nullable=400,
                mandatory1 = 800,
                optional1 = 300,
                optional2 = 700,
                mandatory2 = 600))

        things.forEach { t -> println(t) }
   }

这会产生以下输出:

Thing(mandatory1=1, mandatory2=2, optional1=100, optional2=200, nullable=null)
Thing(mandatory1=1, mandatory2=2, optional1=3, optional2=200, nullable=null)
Thing(mandatory1=1, mandatory2=2, optional1=3, optional2=4, nullable=null)
Thing(mandatory1=1, mandatory2=2, optional1=3, optional2=4, nullable=5)
Thing(mandatory1=1, mandatory2=2, optional1=100, optional2=4, nullable=null)
Thing(mandatory1=1, mandatory2=2, optional1=4, optional2=200, nullable=null)
Thing(mandatory1=1, mandatory2=2, optional1=100, optional2=200, nullable=4)
Thing(mandatory1=800, mandatory2=600, optional1=300, optional2=700, nullable=400)

特别感兴趣的是:

Thing(1, 2, optional2 = 4),

产量

Thing(mandatory1=1, mandatory2=2, optional1=100, optional2=4, nullable=null)

请注意,我可以设置 optional2 ,而无需设置 optional1 。我不确定在Groovy中这是可能的,但是,再说一遍,我远非专家。

作为一个兴趣点,查看生成的字节代码,Kotlin编译器似乎生成一个构造函数,然后重写实例化语句,以在参数列表中的正确点传递可选参数。

那么,对于Groovy专家来说,这在Groovy中是不可能的,还是我还没找到正确的语法?

提前致谢,

西蒙

1 个答案:

答案 0 :(得分:0)

这在groovy中是可能的。例如:

Class Thing{
    def x
    def y
    def z = 5
}

此时,如果你打算做的只是分配值,你根本不需要构造函数。你可以说:

new Thing(x: "Hello", y:"World", z:6) //if you want to overwrite the defualt value of z.

如果您阅读本文档的第1.4节:http://groovy-lang.org/objectorientation.html,它表明您可以选择具有位置构造函数或命名构造函数。

我的例子是使用一个命名参数构造函数,它为调用构造函数的函数提供了更多的功能。

如果你想要任何变量是强制性的,你需要使用位置构造函数,这类似于在直接java中完成它的方式。

如果为您的类定义构造函数,那么您正在使用位置构造函数,并且不能再为该类使用命名参数构造函数。