博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Groovy中for循环的一个奇怪现象引出的"全局变量?"
阅读量:6264 次
发布时间:2019-06-22

本文共 1900 字,大约阅读时间需要 6 分钟。

hot3.png

初学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=0; i<5; i++, j++){    println "$i , $j");}//编译错误(具体位置在 i=0 )//unexpected token: = at line: 1, column: 10

居然不支持, 于是问了下谷姐, 发现确实是不支持. 链接: 

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

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, 01, 12, 23, 34, 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 
 [2]     39  aload_0 [this]     40  ldc 
 [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, 当前类class, 当前类实例, "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"  //输出1println "$j"  //输出2println "$i"  //异常, i不存在

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

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

转载于:https://my.oschina.net/haogrgr/blog/375487

你可能感兴趣的文章
iOS开发中的错误整理,(百思项目,指示器位置)设置控件尺寸和点坐标,先设置尺寸,再设置点坐标...
查看>>
(C/C++学习)7.数组及其访问方式
查看>>
LeetCode——Intersection of Two Linked Lists
查看>>
对拍——我目前可以找到的最简写法
查看>>
js之广告弹出自动关闭
查看>>
axios请求requestBody和formData
查看>>
PSQL_标准API和Interface基本的用法和比较(概念)
查看>>
网站目录
查看>>
APUE-文件和目录(七)符号链接
查看>>
CSS 简介
查看>>
System Verilog基础(二)
查看>>
2018/11/26 Samba服务器配置
查看>>
2018/12/08 PAT刷题 L1-034 点赞
查看>>
如何改变TextBox.PassWordChar的值 转
查看>>
css的工作原理
查看>>
【pip】的安装
查看>>
内存泄漏及其检测工具
查看>>
QT Model based vs Item based
查看>>
[Leetcode]669 Trim a Binary Search Tree
查看>>
Linux C Programing - Arguments(2)
查看>>