简介
我需要通过 key 的动态名称对 map /属性进行空安全访问。 map 本身可以为空。我想出了 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
和 map 键都是 java.lang.String
类型,为什么 map?.(keyName)
不返回值?为什么 map?.(keyName as String)
返回?
链接
最佳答案
括号只是控制评估的优先级。对于 (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
- 当然对于 map 来说更安全。我个人更喜欢第三种方法。
您可能想知道为什么 def map = [(keyName): 'value']
可以使用 keyName
的值作为键,但是 map?。 (keyName)
对使用keyName
的值进行检索不起作用,但原因很简单。用于检索的点表示法仅适用于字符串键。使用括号定义映射适用于任何对象类型。因此,在定义带有括号中的键的映射时,您可以使用任何对象作为键,但是您只能使用带点符号的字符串键从映射中提取对象,因此这里关于括号的语义不同是可以的。
关于dictionary - 为什么通过括号中的变量访问groovy map总是返回null?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44759949/