dictionary - 为什么 Map 不适用于 Groovy 中的 GString?

标签 dictionary groovy gstring

使用以下代码段,我无法检索 gString从 map :

def contents = "contents"
def gString = "$contents"

def map = [(gString): true]

assert map.size() == 1 // Passes
assert gString.hashCode() == map.keySet().first().hashCode() // Passes, same hash code
assert map[gString] // Fails

这到底怎么可能?

断言消息清楚地表明 Groovy 存在严重错误:
assert map[gString] // Fails
       |  ||
       |  |contents
       |  null
       [contents:true]

这与 Why groovy does not see some values in dictionary? 不是同一个问题
那里的第一个答案表明:

You're adding GString instances as keys in your map, then searching for them using String instances.



在这个问题中,我清楚地添加了 GString并尝试检索 GString .

也没有 Why are there different behaviors for the ways of addressing GString keys in maps?也不是 Groovy different results on using equals() and == on a GStringImpl给我一个答案。我不会变异任何东西,也不会混合 StringGString .

最佳答案

tl;博士:您似乎在 Groovy 的运行时参数重载评估中发现了一个错误。

答案:
map[gString]被评估为 map.getAt(gString)在运行时直接通过 Groovy 的运算符重载机制。到目前为止,一切都很好,但现在一切都开始出错了。 Java LinkedHashMap类(class)没有 getAt方法在它的类型层次结构中的任何地方,所以 Groovy 必须使用动态关联的 mixin 方法来代替(实际上该语句有点颠倒。Groovy 在使用类层次结构中声明的方法之前使用 mixin 方法。)

因此,长话短说,Groovy 解析 map.getAt(gString)使用分类方法DefaultGroovyMethods.getAt() .容易,对吧?除了此方法有大量不同的参数重载,其中一些可能适用,尤其是当您考虑 Groovy 的默认参数强制时。

不幸的是,没有选择 DefaultGroovyMethods.getAt(Map<K,V>,K) ,这似乎是一个完美的匹配,Groovy 选择了 DefaultGroovyMethods.getAt(Object,String) , 强制 GString关键参数变成 String .由于实际 key 实际上是 GString ,该方法最终无法找到该值。

对我来说,真正的杀手是,如果直接从代码中执行参数重载解析(而不是在运算符解析和类别方法选择之后),那么 Groovy 会做出正确的重载选择!也就是说,如果替换这个表达式:

map[gString]

用这个表达:
DefaultGroovyMethods.getAt(map,gString)

然后正确解析参数重载,并找到并返回正确的值。

关于dictionary - 为什么 Map 不适用于 Groovy 中的 GString?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39141245/

相关文章:

python - 将列表的列表转换为字典的字典(Python)

python - 按列表中的值对字典键进行排序?

intellij-idea - 如何将变量传递给 Intellij IDEA 实时模板 groovy 脚本中的 groovy 代码?

javascript - Raphael js toFront() 方法扭曲

arrays - 如何在swift4中使用key访问数组

groovy - SoapUI Groovy 脚本

grails - 如何告诉 groovy/grails 不要尝试 "re-encode"二进制数据? (修改后的标题)

security - 不安全使用用户提供的 GString :s in Groovy/Grails

groovy - 为什么对于这个常规映射,对 containsKey() 的调用失败?

sql - 从 GString 转义点