Dictionary 为什么通过括号中的变量访问groovy映射总是返回null? 简明的

Dictionary 为什么通过括号中的变量访问groovy映射总是返回null? 简明的,dictionary,groovy,Dictionary,Groovy,我需要通过密钥的动态名称对映射/属性进行空安全访问。映射本身可以为空。我想到了map?(keyName),但不知道为什么它不能像预期的那样工作,并且总是返回null 代码示例 问题: 如果keyName和map键的类型都是java.lang.String为什么map?(keyName)不返回值?为什么map?(keyName作为字符串)返回? ​ 链接 签入Groovy正在将map?(keyName)解析为map?.get('keyName')。使用map?.keyName会产生相同的结果: d

我需要通过密钥的动态名称对映射/属性进行空安全访问。映射本身可以为空。我想到了
map?(keyName)
,但不知道为什么它不能像预期的那样工作,并且总是返回
null

代码示例 问题: 如果
keyName
和map键的类型都是
java.lang.String
为什么
map?(keyName)
不返回值?为什么
map?(keyName作为字符串)
返回? ​

链接
签入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'

括号仅控制求值的优先级。对于
(keyName)
,括号中没有任何可计算的内容,因此括号没有意义,
map?(keyName)
map?.keyName
相同,意思是
map?.get('keyName')

使用
map?(keyName作为字符串)
时,括号中有要计算的内容,因此它首先计算并解析为
map?'key'
,意思是
map?.get('key')

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

  • map?(keyName作为字符串)
  • map?.get(keyName)
  • map?“$keyName”
  • map[keyName]
虽然最后一个选项不是
null
,但对于地图来说当然更安全。我个人更喜欢第三种方法


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

您能提供一些描述这一点的链接吗?我指的是Groovy通常是如何解决这种语法情况的。因为对我来说,
map.(keyName)
map.(keyName作为字符串)
都应该解析为变量,并且只有
map。keyName
应该解析为constantI快速浏览了一遍,但找不到太多。我想它还没有被记录下来。这种语法对我来说是新的。
[class java.lang.String]: [class java.lang.String]
keyName class is [class java.lang.String]
null
value
value
value
def map = [key: 'value', keyName: 'gotcha']
def keyName = 'key'

result = map?.(keyName)

assert result == 'gotcha'
assert map?.keyName == 'gotcha'