加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Groovy中for循环的一个奇怪现象引出的"全局变量?"

发布时间:2020-12-14 16:48:39 所属栏目:大数据 来源:网络整理
导读:初学Groovy,用for循环的时候出现了点问题,记录下来 环境: Eclipse4.4,Groovy编译器版本 2.3.7 Java版本:1.8_23_x86 看下面在Java中比较常见的代码 for(int?i=0,?j=0;?i5;?i++,?j++){????System.out.println(i?+?",?"?+?j);} 于是我想当然的在Groovy中照着写

初学Groovy,用for循环的时候出现了点问题,记录下来

环境: Eclipse4.4,Groovy编译器版本 2.3.7 Java版本:1.8_23_x86

看下面在Java中比较常见的代码

for(int?i=0,?j=0;?i<5;?i++,?j++){
????System.out.println(i?+?",?"?+?j);
}


于是我想当然的在Groovy中照着写了一个,

for(int?i=0,?j++){
????println?"$i?,?$j");
}

//编译错误(具体位置在?i=0?)
//unexpected?token:?=?at?line:?1,?column:?10

居然不支持,于是问了下谷姐,发现确实是不支持. 链接:?http://stackoverflow.com/questions/14535123/groovy-for-loop-with-multiple-counters


机智如我,有怎么会被区区编译错误拦住,换个方式

for(int?i=j=0;?i<5;?i++,?j++){
????println?"$i,?$j"
}

//编译错误(具体位置在?,?j++)
//expecting?')',?found?','?at?line:?1,?column:?24


好吧,不能j++就算了,我放循环里面去,终于可以执行了

for(int?i=j=0;?i<5;?i++){
????println?"$i,?$j"
????j++
}

//再减少一行
for(int?i=j=0;?i<5;?i=++j){
????println?"$i,?$j"
}

//输出
0,?0
1,?1
2,?2
3,?3
4,?4


好了,不报错了,舒服了...那么问题来了,为什么这么可以~~~~~于是抄起字节码开看,关键位置

?????28??goto?169
?????31??iconst_0
?????32??istore_2
?????33??iload_2
?????34??invokestatic?java.lang.Integer.valueOf(int)?:?java.lang.Integer?[67]
?????37??ldc?<Class?main.Temp>?[2]
?????39??aload_0?[this]
?????40??ldc?<String?"j">?[69]
?????42??invokestatic?org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setGroovyObjectProperty(java.lang.Object,?java.lang.Class,?groovy.lang.GroovyObject,?java.lang.String)?:?void?[73]
?????45??iload_2
?????46??istore_3?[i]
?????47??iload_3?[i]


原来如此,大概翻译过来就是(真是的更复杂点,但大概是这样的,i++这样的代码似乎变成了方法调用)

ScriptBytecodeAdapter.setGroovyObjectProperty(0,?当前类class,?当前类实例,?"j");
for(int?i?=?0;?i<5;){
????println?xxxxx
????ScriptBytecodeAdapter.setGroovyObjectProperty(PogoGetPropertySite.getProperty("j")?+?1,?"j");
????i?=?PogoGetPropertySite.getProperty("j")
}


大家可以断点试试.

那么为什么会出现这个情况了,猜测: 可能是类似于js全局变量的概念

int i = j = 0 被翻译为了

int i= 0?

j = 0?

而全局变量底层实现是放在一个LinkedHashMap中的.

由于是脚本,估计j被当作全局变量类似的东西,来证明下猜想

for(int?i=j=0;?i<2;?i=++j){
????k?=?1
????println?"$i,?$j"
}

println?"$k"??//输出1
println?"$j"??//输出2
println?"$i"??//异常,?i不存在


可以看到,i的范围在for内,而j在for外也能访问,有点类似于全局变量.

最后说明下,上面的代码放在main方法里面是会报错的~~~只能实例方法中,main是静态方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读