带有可选参数的 Groovy 方法

我想为一个 webservice 编写一个包装器方法,该服务接受2个强制参数和3个可选参数。

为了获得一个更短的示例,我想让下面的代码工作起来

def myMethod(pParm1='1', pParm2='2') {
println "${pParm1}${pParm2}"
}


myMethod();
myMethod('a')
myMethod(pParm2:'a') // doesn't work as expected
myMethod('b','c')

输出结果是:

12
a2
[pParm2:a]2
a2
bc

我想实现的是给出一个参数并得到 1a作为结果。 这可能吗(以最懒惰的方式) ?

141564 次浏览

现在不能这么做,密码

def myMethod(pParm1='1', pParm2='2'){
println "${pParm1}${pParm2}"
}

基本上使得 groovy 创建以下方法:

Object myMethod( pParm1, pParm2 ) {
println "$pParm1$pParm2"
}


Object myMethod( pParm1 ) {
this.myMethod( pParm1, '2' )
}


Object myMethod() {
this.myMethod( '1', '2' )
}

另一种方法是在第一个参数中使用一个可选的 Map:

def myMethod( Map map = [:], String mandatory1, String mandatory2 ){
println "${mandatory1} ${mandatory2} ${map.parm1 ?: '1'} ${map.parm2 ?: '2'}"
}


myMethod( 'a', 'b' )                // prints 'a b 1 2'
myMethod( 'a', 'b', parm1:'value' ) // prints 'a b value 2'
myMethod( 'a', 'b', parm2:'2nd')    // prints 'a b 1 2nd'

显然,记录这一点是为了让其他人知道在神奇的 map中会发生什么,默认值是什么留给读者; -)

可以使用具有默认值的参数。

def someMethod(def mandatory,def optional=null){}

如果参数“可选”不存在,则转为“ null”。

只是提姆答案的简化。这样做的常用方法是使用映射,正如前面所建议的那样,但是接下来让我们将强制参数也放在映射中。这看起来像这样:

def someMethod(def args) {
println "MANDATORY1=${args.mandatory1}"
println "MANDATORY2=${args.mandatory2}"
println "OPTIONAL1=${args?.optional1}"
println "OPTIONAL2=${args?.optional2}"
}


someMethod mandatory1:1, mandatory2:2, optional1:3

输出:

MANDATORY1=1
MANDATORY2=2
OPTIONAL1=3
OPTIONAL2=null

这样看起来更好,其优点是您可以随意更改参数的顺序。

我们可以用两种方法处理可选参数

  1. 使用 null值创建方法参数:
def generateReview(def id, def createDate=null) {
return new Review(id, createDate ?: new Date()) // ?: short hand of ternary operator
}


generateReview(id) // createDate is not passed
generateReview(id, createDate) // createDate is passed
  1. 使用 JavaOptional.of()
def generateReview(def id, Optional<Date> createDate) {
return new Review(id, createDate.isPresent() ? createDate.get() : new Date())
}


generateReview(id, Optional.empty()) // createDate is not passed
generateReview(id, Optional.of(createDate)) // createDate is passed