【问题标题】:Groovy Meta Programming: Override Map invokeMethodGroovy 元编程:覆盖 Map invokeMethod
【发布时间】:2019-05-08 21:07:46
【问题描述】:

我有一个 java Map<String,Object>,我正在使用 groovy 的魔法访问它

myMap.property1.nestedProperty1.nestedNestedProperty

这太棒了,我知道我可以像这样安全地导航:

myMap?.property1?.nestedProperty1?.nestedNestedProperty

但是,当我遍历一个巨大的分层嵌套地图时,记住始终安全导航会变得乏味。

我认为 groovy 通过使用 invokeMethod 覆盖来实现嵌套图导航。

对于我来说,在默认情况下修改该行为以安全导航而无需每次都执行?. 的推荐/最佳方法是什么?

我打算只覆盖我的地图对象metaClass.invokeMethod,而不是第一类。

PS:我一直在徒劳地搜索 groovy 源代码。有人还可以指出 groovy 在 Java Map 实现中究竟在哪里实现了这个功能?

【问题讨论】:

    标签: groovy metaprogramming


    【解决方案1】:

    您可以尝试的一件事是使用 ConfigObject,它已经具有这种“安全性”。

    ConfigObject conf = myMap as ConfigObject
    

    现在您可以执行conf.property1.nestedProperty1.nestedNestedProperty 并且它总是会解决,即使原始地图中缺少任何级别。

    但是,完成后的结果,如果缺少任何部分,则不是 null,而是 isEmpty() 为 true 的 ConfigObject。如果愿意,您可以使用instanceof 进行测试,所以:

    myMap?.property1?.nestedProperty1?.nestedNestedProperty
    

    相当于:

    ConfigObject conf = myMap as ConfigObject
    Object value = conf.property1.nestedProperty1.nestedNestedProperty
    value = (value instanceof ConfigObject ) ? null: value
    

    您可以很容易地编写一个更干净地执行上述操作的方法。

    http://docs.groovy-lang.org/2.4.9/html/gapi/groovy/util/ConfigObject.html

    【讨论】:

    • 这很有趣,但现在,我觉得我已经从期望人们记住使用安全导航到期望人们最终进行此检查,不幸的是。
    • 问题是,您不能在 null 上调用方法,并且您说您希望中间失败返回 null,因为您无法告诉它是中间失败。这些要求有冲突。
    • 我想我看到了这个问题。我看到?. 作为在空对象上调用的单个运算符,我想弄清楚如何将. 转换为?.,但我想你在这种情况下在null 上调用? 并返回如果代表实际上是null,则立即。
    猜你喜欢
    • 2012-04-24
    • 2013-06-30
    • 1970-01-01
    • 2011-05-01
    • 2015-09-21
    • 2014-05-06
    • 2018-05-06
    相关资源
    最近更新 更多