我试图确定,纯粹是出于兴趣,是否有可能通过使用命名和默认构造函数参数完全消除在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中是不可能的,还是我还没找到正确的语法?
提前致谢,
西蒙
答案 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中完成它的方式。
如果为您的类定义构造函数,那么您正在使用位置构造函数,并且不能再为该类使用命名参数构造函数。