【问题标题】:Why accessing to groovy map through variable in parentheses always returns null?为什么通过括号中的变量访问 groovy map 总是返回 null?
【发布时间】:2017-06-26 12:38:48
【问题描述】:

简介

我需要通过键的动态名称对映射/属性进行空安全访问。地图本身可以为空。我想出了map?.(keyName),但想知道为什么它没有按预期工作并且总是返回null

代码示例

def map = [key: 'value']
def keyName = 'key'

map.each({ key, value -> println("[${key.class}]: [${value.class}]")})
println("keyName class is [${keyName.class}]")

println(map?.(keyName))                        // null  <--------- My question

// Alternatives that work well
println(map?.(keyName as String))              // value
println(map?.(keyName as java.lang.String))    // value
println(map?.get(keyName))                     // value

​

输出

[class java.lang.String]: [class java.lang.String]
keyName class is [class java.lang.String]
null
value
value
value

问题

如果keyName 和映射键都是java.lang.String 类型,为什么map?.(keyName) 不返回值?为什么map?.(keyName as String) 返回? ​

链接

签到Groovy web console

【问题讨论】:

    标签: dictionary groovy


    【解决方案1】:

    括号只是控制评估的优先级。对于(keyName),括号中没有要计算的内容,因此括号没有意义,map?.(keyName)map?.keyName 相同,即map?.get('keyName')

    对于map?.(keyName as String),括号中有一些要评估的内容,所以它首先评估并解析为map?.'key',这意味着map?.get('key')

    如果你想使用动态键值,你必须确保它是由某个表达式计算的。各种选择(一些您已经找到)是:

    • map?.(keyName as String)
    • map?.get(keyName)
    • map?."$keyName"
    • map[keyName]

    虽然最后一个选项不是null-safer 当然关于地图。我个人更喜欢第三种方法。

    您可能想知道为什么def map = [(keyName): 'value'] 可以使用keyName 的值作为键,而map?.(keyName) 不能使用keyName 的值进行检索,但原因很简单。用于检索的点表示法仅适用于字符串键。使用括号定义映射适用于任何对象类型。因此,在定义带有括号中的键的映射时,您可以使用任何对象作为键,但您只能从带有点符号的字符串键的映射中提取对象,因此这里的括号中的语义不同是可以的。

    【讨论】:

      【解决方案2】:

      Groovy 将 map?.(keyName) 解析为 map?.get('keyName')。使用map?.keyName 会产生相同的结果:

      def map = [key: 'value', keyName: 'gotcha']
      def keyName = 'key'
      
      result = map?.(keyName)
      
      assert result == 'gotcha'
      assert map?.keyName == 'gotcha'
      

      【讨论】:

      • 你能提供一些描述这个的链接吗?我的意思是一般来说 Groovy 如何解决这些语法案例。因为对我来说map.(keyName)map.(keyName as String) 都应该被解析为变量,只有map.keyName 应该被解析为常量
      • 我快速浏览了groovy-lang.org/syntax.html,但找不到太多。我想它还没有记录。这种语法对我来说是新的。
      猜你喜欢
      • 2018-09-30
      • 1970-01-01
      • 2018-12-31
      • 2014-09-12
      • 2019-09-18
      • 2014-09-02
      • 2015-02-27
      • 2021-01-10
      • 1970-01-01
      相关资源
      最近更新 更多