Groovy 命名参数会导致参数分配发生切换——有什么办法可以解决这个问题吗?

2024-02-21

Groovy 会将所有命名参数收集到一个映射中,并将其作为第一个参数传递到方法中。这看起来很简洁,但是在尝试让它工作之后,它似乎真的无法使用。

所以问题是这样的方法:

def method(paramMap, specificVar1 = 7, specificVar2 = 14)

当您使用如下方式调用此方法时:

method(12, extraValue: "hello")

你得到的几乎是你所期望的:

assert 12 == specificVar1
assert 14 == specificVar2
assert [extraValue:"hello"] == paramMap

不错,有道理。问题是,如果你假设Mapparams 是可选的,那么你最终可以得到如下值:

method(12)
assert paramMap == 12
assert specificVar1 == 7 // default values
assert specificVar2 == 14

该标量应该进入 SpecificVar,而不是映射。如果我在方法中专门输入地图:

def method(Map paramMap, specificVar1 = 7, specificVar2 = 14)

then method(12, extraValue: "hello")就像以前一样工作,但是method(12)抛出一个ClassCastException。这看起来不太好用。有什么办法可以做到吗Map“粘性”,这样如果没有的话它就会是空的Map参数?

Note:

十年后,由于收到 2500 次浏览的通知,我再次访问了此内容。接受的答案的重载解决方案是完美的。基本上是第二种方法:

def method(specificVar1 = 7, specificVar2 = 14) 
{
    method([:],specificVar1, specificVar2)
}

似乎适用于我的所有测试用例,无论是否有默认值。

如果我要进一步追求这个目标,我可能会尝试找出如何为我喜欢从 repl 运行的一堆方法综合生成这样的重载。


设置参数的默认值会产生重载方法,并且从左到右组合,因此很难制作method(12)并且还能够传递地图条目。

你的方法def method(paramMap, specificVar1=7, specificVar2=14)将生成以下方法:

Object Maps.method(java.lang.Object)
Object Maps.method(java.lang.Object,java.lang.Object)
Object Maps.method(java.lang.Object,java.lang.Object,java.lang.Object)

以及带有地图参数的完全类型化方法:

def method3(Map paramMap=[:], Integer specificVar1=7, Integer specificVar2=14) {
}

会生成以下方法:

Object Maps.method3()
Object Maps.method3(java.util.Map)
Object Maps.method3(java.util.Map,java.lang.Integer)
Object Maps.method3(java.util.Map,java.lang.Integer,java.lang.Integer)

(没有合适的方法method(12)).

此外,传递给该方法的条目将被收集并插入到第一个map范围。方法如下:

def method4(Integer specificVar1=7, Integer specificVar2=14, Map map=[:]) {

生成:

Object Maps.method4()
Object Maps.method4(java.lang.Integer)
Object Maps.method4(java.lang.Integer,java.lang.Integer)
Object Maps.method4(java.lang.Integer,java.lang.Integer,java.util.Map)

Thus, method4 12, a:'b'失败并显示:

No signature of method: Maps.method4() is applicable for argument types: 
  (java.util.LinkedHashMap, java.lang.Integer) values: [[a:b], 12]

所以,不,我认为你不能使用地图做你想做的事:-)。


解决方案一:

如果您需要纯动态解决方案,则可以使用单个映射参数:

def method5(Map map) {
  def specificVar1 = map.specificVar1 ?: 7
  def specificVar2 = map.specificVar2 ?: 14
}

解决方案2(已更新):

您可以创建一个类来表示参数。使用映射强制到对象中是可静态编译的,并且是它的语法糖。

@groovy.transform.CompileStatic
class Maps {
  def method6(Foo foo) { "$foo.params, $foo.specificVar1, $foo.specificVar2" }
  def method6(Map map) { method6 map as Foo }

  static main(args) {
    def maps = new Maps()

    assert maps.method6(params: [a: 'b', c: 'd'], specificVar1: 40) ==
        "[a:b, c:d], 40, 14"

    assert maps.method6(new Foo(params: [a: 'b', c: 'd'], specificVar2: 21)) == 
        "[a:b, c:d], 7, 21"
  }
}

class Foo {
  def specificVar1 = 7, specificVar2 = 14, params = [:]
}

解决方案3:

一个重载方法。

def method6(Map paramMap, Integer specificVar1=7, Integer specificVar2=14) {
  "$paramMap, $specificVar1, $specificVar2"
}

def method6(Integer specificVar1=7, Integer specificVar2=14) {
  method6 [:], specificVar1, specificVar2
}


assert method6( 12 ) == "[:], 12, 14"
assert method6( ) == "[:], 7, 14"
assert method6( a:'b', 18 ) == "[a:b], 18, 14"
assert method6( 18, a:'b', 27 ) == "[a:b], 18, 27"
assert method6( 90, 100 ) == "[:], 90, 100"
assert method6( a:'b', 140, c:'d' ) == "[a:b, c:d], 140, 14"

地图版本方法不能有默认参数,否则两个方法都会生成无参数method6这些都会发生冲突。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Groovy 命名参数会导致参数分配发生切换——有什么办法可以解决这个问题吗? 的相关文章

随机推荐

  • 如何在 Freemarker 模板中访问 Spring 应用程序属性?

    我有使用 Spring 3 1 的 Java web 应用程序 以及用于渲染视图的 Freemarker 模板 我想根据特定应用程序属性的真 假值有条件地在视图中显示链接 我在中定义了以下应用程序属性src main resources a
  • 如何获取列表视图位置?

    我在 Listview onListItemClick 方法中遇到问题 我没有得到列表的位置 这是我的代码请帮助我 求职信选择 xml
  • Angular:用逗号格式化数字

    标题非常概括了我的需求 123456789 gt 123 456 789 12345 gt 12 345 获得这种转化的最佳方法是什么 不要建议在 Angular 2 中使用货币管道 因为我不需要在输出前添加 或货币符号 像这样使用 Dec
  • 将某些日期替换为 NA

    我正在尝试用 NA 替换某些日期 我尝试了以下方法 但没有成功 df lt data frame dates seq Date as Date 1910 01 01 as Date 1999 01 01 days gt mutate if
  • Maven Release-plugin“标签已存在”对于不存在的标签

    我的设置 git 存储库在Atlassian Stash 服务器和Atlassian Bamboo 我在用着Maven 3 1 1与release plugin 2 3 2 该计划在Bamboo看起来像这样 退房自git 存储库 执行一个c
  • 在Android中设置Crouton消息的持续时间

    我已经开始使用 Crouton 消息而不是 toast 消息 因为我可以配置持续时间 有什么方法可以继续显示油煎面包块消息 直到发生特定事件 而不是以明确的单位指定时间 您可以将油煎面包块的持续时间设置为INFINITE从内部Configu
  • 如何从 C# Web 服务生成 WSDL 文件

    我创建了一个像这样的WebService WebService Namespace http ns WebServiceBinding ConformsTo WsiProfiles BasicProfile1 1 public class
  • 当应用程序处于后台时,活动在“最近”中不可见

    问题描述 在我的一个应用程序中 我看到了相当奇怪的行为 当我的应用程序在前台运行 最顶层的应用程序 时 我可以在系统的 最近 中看到其活动 但一旦我将其置于后台 相同的活动 即AccountsActivity 刚才列出的内容不再出现在 最近
  • 解组非根元素时的 JAXB 模式验证

    当您使用 JAXB 解组整个 XML 时 您可以设置 XML 模式以在解析期间启用验证 javax xml validation Schema schema jaxbUnmarshaller JAXBContext newInstance
  • 逐行读取并存储在结构体数组中

    我正在尝试从文本文件中逐行读取行并将其存储在数组中 txt 文件中有一些问题将询问玩家 下面是一些问题 1 N r kom potatisen till Europa A 1300 talet B 1500 talet C 900 tale
  • 禁用 Maven 内部版本号插件

    目前我们正在开发一个大型 Maven 项目 该项目有大约 100 个模块 其中一些还有子模块 一些模块使用 Maven Build Number 插件 该项目是在 Subversion 下托管的 最近我们的开发团队开始在本地使用 git 克
  • 使用 firebase 作业调度程序安排重复作业

    我试图每 10 分钟将 Android 设备的位置发布到服务器一次 我正在使用 firebase 作业调度程序来执行此操作 FirebaseJobDispatcher dispatcher new FirebaseJobDispatcher
  • 仅针对单个模式生成流畅的代码

    有没有办法让 Slick 的代码生成仅为单个模式生成代码 你说 公开 我有一些扩展可以创建大量的表 例如 postgis pg jobman 从而使 slick 生成的代码变得巨大 将此代码与适当的值和模式名称一起使用 object Cod
  • 如何在eclipse中缩进jsp页面

    刚开始使用 jsp 我的页面看起来很糟糕 请建议一种缩进的方法 thanks 首先确保您安装了 Web Tools 如果没有 请检查此链接 http download eclipse org webtools updates http do
  • 提升 Asio 单线程性能

    我正在实现需要维护大量 100K 或更多 长期连接的自定义服务器 服务器只是在套接字之间传递消息 并且不进行任何认真的数据处理 消息很小 但每秒都会接收 发送许多消息 减少延迟是目标之一 我意识到使用多核不会提高性能 因此我决定通过调用在单
  • Python 中的自定义错误消息

    所以我正在练习一些单元测试 我有一个关于错误消息的问题 我正在尝试创建一条自定义错误消息 该消息将在测试失败时显示 这是一个基本的 Hello World 程序 测试运行良好 一切正常 但这是我收到的错误消息 F FAIL test Str
  • ADO.NET 数据表约束如何影响性能?

    DataTable 上的约束 例如主键和唯一约束 是否可以像在 SQL Server 中一样使 Select 更高效 或者他们的唯一目的是对数据执行规则 myDT Constraints Add PK myDT Columns Unique
  • 即使链接具有定义的库后,也会出现“未定义的函数引用”问题

    我正在尝试使用 o so a 文件创建可执行文件 这是我的构建命令 pkgs gcc v4 8 3 bin gcc L usr X11R6 lib O2 DUSE FLEX Wall Wno char subscripts fPIC DLI
  • Visual Studio 调试器在内联代码中速度变慢

    自从我从 vs2005 升级到 Visual Studio 2008 以来 我在调试大型项目时发现了一个非常烦人的行为 如果我尝试单步执行内联代码 调试器似乎会锁定数十秒 每次我进入这样的函数时 都会出现类似的停顿 有没有人经历过这种情况并
  • Groovy 命名参数会导致参数分配发生切换——有什么办法可以解决这个问题吗?

    Groovy 会将所有命名参数收集到一个映射中 并将其作为第一个参数传递到方法中 这看起来很简洁 但是在尝试让它工作之后 它似乎真的无法使用 所以问题是这样的方法 def method paramMap specificVar1 7 spe