使用documented mixture of named and positional arguments(或具有默认值的args),如何在不指定任何命名参数的情况下调用方法?
我正在尝试扩展现有的共享方法而不破坏其他人的代码,这种方法看起来很有希望,但是以下示例失败了:
def test(Map args, some, thing='default value'){
"$some $thing";
}
//good - adding any named parameter works
//test('yet', 'another good', anything:'notneeded');
//but not specifying named parameter fails
test('this', 'fails');
我找不到有关此行为的文档,而且看起来很奇怪。
答案 0 :(得分:0)
这取决于现有方法签名的外观。假设您有一个带有1个参数的现有方法,如下所示:
def test(String input) { ... }
如果要添加传递一个附加位置参数的功能,则只需添加一个重载即可:
def test(String input, String output) { ... }
如果要添加可选的命名参数,则可以添加此重载:
def test(Map namedArgs, String input) { ... }
如果调用“ test('')”,它将运行原始方法。 “ test('one','two')”将运行secobd版本。 “ test('one',two:'two')”将运行第三个。
如果要支持2个位置参数和一个或多个命名参数,则可能需要添加第4个重载。
答案 1 :(得分:0)
可以通过为map参数设置默认值来使方法的命名参数为可选。例如:
def test(Map args = [:], some, thing='default value'){
"$some $thing";
}
这将允许以下任何调用成功:
test('some value')
test('some value', 'thing value')
test('some value', extra1: 'e1', extra2: 'e2')
test(extra: 'val', 'some value', 'thing value')
答案 2 :(得分:0)
groovy解析器需要一些信息来确定要执行的方法。
所以,如果您写:
test('yet', 'another good', anything:'notneeded')
这被翻译成:
test([anything:'notneeded'], 'yet', 'another good')
即所有已命名的参数化样式的参数(带有冒号)都放入地图中,并放置在参数列表的开头。所有其余参数都放置在其后。
因此Groovy现在正在寻找签名test(Map, String, String)
并正确找到您的方法。
如果没有命名参数,则不会进行此转换,并且签名将是test(String, String)
,它没有匹配方法。
所以解决方案是创建一个与调用匹配的附加方法,而无需命名参数:
def test(some, thing='default value'){
test([:], some, thing)
}
这样,支持命名和未命名的呼叫。