第一:不要在你的 hashmap 键中使用 GStrings。曾经。您在检索项目时几乎总是会遇到问题,因为GString不是字符串(该页面上的红色框),并且没有相同的哈希值。相反,请使用以下选项之一:
def key = 'key'
['key': value]
[(key): value]
[("some $key".toString()): value]
这可确保您在使用字符串时始终获得结果。(因此,对于查找,也始终使用字符串。)
我不是 100% 确定你为什么会看到奇怪的行为,但我有一个可靠的猜测。该get()
方法是 Java 方法,而数组样式(可能还有属性样式)查找是使用getAt()
Groovy (GDK) 方法实现的。我的猜测是 Groovy 方法知道 GStrings,并默默地处理转换以确保您不会被绊倒。
最简单的解决方案是始终使用getAt()
,而不是get
:
def m = ['smart-1':[stuff:'asdf']]
println m.getClass()
def p = [id:1]
println m."smart-$p.id"
println m["smart-$p.id"]
println m.getAt("smart-$p.id")
println m.'smart-1'
println m['smart-1']
println m.getAt('smart-1')
哪个工作正常。
更好的解决方案是确保在查找值时使用字符串,如下所示:
println m.get("smart-$p.id".toString())
这也有效。我比较喜欢这个方法,因为直接调用方法的时候,更清楚你的key是String。在使用数组样式或属性样式访问器时,我仍然会使用普通的 GString,因为那是标准的 Groovy 语法。
在集成测试中,我看到了相反的行为——我只能使用 m.get(GStringImpl)(而不是 m.get(String))来获取 HashMap 的内容。
这很可能是因为您在哈希图中的键是 GString。
如果 GString 没有任何变量,Groovy 编译器会默默地将其转换为 String 字面量(性能更好),这就是为什么上面的示例实际上使用 String 作为键,但查找使用的是 GString。
例如
"Hello $name" -> GString('Hello $name')
"Hello Bob" -> 'Hello Bob'
最后的想法:只要你在 groovy 中,就不要使用get()
,因为 Groovy 提供了更简洁[]
和属性的语法。