Dictionary 为什么我不能得到与Groovy中映射的GString完全相同的GString?
使用以下代码段,我无法从映射中检索Dictionary 为什么我不能得到与Groovy中映射的GString完全相同的GString?,dictionary,groovy,gstring,Dictionary,Groovy,Gstring,使用以下代码段,我无法从映射中检索gString: 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 gString.is(map.
gString
:
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 gString.is(map.keySet().first()) // Passes, exactly the same object
assert map[gString] // Fails
这怎么可能?
这里有趣的是,map.get(map.keySet()[0])
工作正常,而map.get[map.keySet()[0]]
工作不正常
断言消息清楚地表明存在错误:
assert map[gString] // Fails
| ||
| |contents
| null
[contents:true]
这和我的问题不一样
第一个答案是:
您将GString实例添加为地图中的键,然后使用字符串实例搜索它们
在这个问题中,我清楚地添加了GString
,并尝试检索GString
我也没有答案。我不会变异任何东西,也不会将
String
与GString
混合使用。也没有帮助。tl;dr:您似乎在Groovy的运行时参数重载计算中发现了一个错误
回答:
map[gString]
在运行时通过Groovy的操作符重载机制直接计算为map.getAt(gString)
。到目前为止,一切都很好,但现在一切都开始出错了。JavaLinkedHashMap
类在其类型层次结构中的任何位置都没有getAt
方法,因此Groovy必须使用动态关联的mixin方法(实际上该语句有点颠倒。Groovy在使用类层次结构中声明的方法之前使用mixin方法)
因此,长话短说,Groovy解析map.getAt(gString)
使用category方法DefaultGroovyMethods.getAt()
。很简单,对吧?除了此方法有大量不同的参数重载,其中一些可能适用,特别是在考虑Groovy的默认参数强制时
不幸的是,Groovy没有选择似乎是完美匹配的DefaultGroovyMethods.getAt(Map,K)
,而是选择了DefaultGroovyMethods.getAt(Object,String)
,这将GString
键参数强制为字符串。由于实际键实际上是一个GString
,因此该方法最终无法找到值
对我来说,真正的杀手是,如果参数重载解析直接从代码中执行(而不是在运算符解析和类别方法选择之后),那么Groovy会做出正确的重载选择!也就是说,如果替换此表达式:
map[gString]
DefaultGroovyMethods.getAt(map,gString)
用这句话:
map[gString]
DefaultGroovyMethods.getAt(map,gString)
然后正确地解决了参数重载问题,找到并返回了正确的值。这是一个很好的问题,也许您应该在票据中添加map.get[map.keySet()[0]]
不起作用,但map.get(map.keySet()[0])
效果很好。@Vampire谢谢,编辑的问题-确实非常有趣,只需添加doingmap[gString]=1代码>生成了这个有趣的地图[内容:true,内容:1]
。几乎就好像getAt
/putAt
使用gstring的字符串表示法一样……请参见我对您的(被错误地忽略的)问题的评论:。你似乎发现了一个合法的bug。Groovy运行时似乎在动态地将map[gString]
映射到DefaultGroovyMethods.getAt()
的错误重载。