Groovy JsonBuilder循环添加数组元素时变量值异常问题咨询
问题原因与解决方案
问题根源
你遇到的是Groovy中闭包变量捕获特性导致的问题:
你添加到myList数组里的是闭包对象({ sval t.asString(); ival t }),这些闭包并不会在循环执行时立即生成对应的JSON节点,而是等到整个JSON被序列化输出的时候才会被执行。此时循环已经完全结束,变量t的最终值是2,所以所有闭包都会读取这个最终值,导致生成的数组元素全是t=2的结果。
修复方案
方案1:用局部变量保存循环当前值
在每次循环中创建一个局部变量,让闭包捕获这个局部变量的引用(每次循环的局部变量是独立实例):
def builder = new JsonBuilder() def json = builder.si { content 'test' } json.si.put('myList', []) for (t=0; t < 2; t++) { def currentT = t // 每次循环创建独立变量,保存当前t的值 json.si.myList.add({ sval currentT.asString() ival currentT }) }
方案2:更符合JsonBuilder的原生写法
直接在JsonBuilder的构建闭包中生成数组,避免事后添加闭包的操作,写法更简洁也更不易出错:
def builder = new JsonBuilder() builder.si { content 'test' // 直接通过collect生成数组元素 myList (0..1).collect { num -> [ sval: num.toString(), ival: num ] } }
或者用each循环在myList的闭包里直接构建每个元素:
def builder = new JsonBuilder() builder.si { content 'test' myList { (0..1).each { num -> item { sval num.toString() ival num } } } }
内容的提问来源于stack exchange,提问作者Frank Leverenz
相关产品推荐
相关产品推荐

