Sun*_*nov 6 groovy named-parameters
使用已记录的命名和位置参数(或具有默认值的 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');???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
我无法找到有关此行为的文档,而且看起来很奇怪。
groovy 解析器需要一些信息来确定要执行的方法。
所以如果你写:
test('yet', 'another good', anything:'notneeded')
Run Code Online (Sandbox Code Playgroud)
这被翻译成:
test([anything:'notneeded'], 'yet', 'another good')
Run Code Online (Sandbox Code Playgroud)
即所有命名参数样式的参数(带有冒号)都被放入一个映射中并放置在参数列表的开头。所有剩余的参数都放置在此之后。
所以 Groovy 现在会查找签名test(Map, String, String)
并正确找到您的方法。
如果没有命名参数,则不会发生这种转换,并且签名将为test(String, String)
,它没有匹配的方法。
所以解决方案是创建一个额外的方法来匹配没有命名参数的调用:
?def test(some, thing='default value'){
test([:], some, thing)
}
Run Code Online (Sandbox Code Playgroud)
这样,既支持命名调用又支持未命名调用。
这取决于现有方法签名的样子。假设您有一个带有 1 个参数的现有方法,如下所示:
def test(String input) { ... }
Run Code Online (Sandbox Code Playgroud)
如果您想添加传递一个附加位置参数的功能,您只需添加一个重载即可:
def test(String input, String output) { ... }
Run Code Online (Sandbox Code Playgroud)
如果您想添加可选的命名参数,您可以添加此重载:
def test(Map namedArgs, String input) { ... }
Run Code Online (Sandbox Code Playgroud)
如果您调用“test('')”,它将运行原始方法。“test('one', 'two')”将运行 secobd 版本。“test('one',two: 'two')”将运行第三个。
如果您想支持 2 个位置参数和一个或多个命名参数,您可能需要添加第四个重载。
归档时间: |
|
查看次数: |
6699 次 |
最近记录: |