Groovy++使用注意的时候
2010-11-30 11:46
211 查看
最近使用Groovy处理一些数据工作,发现其速度慢的不行,也懒得对代码进行优化,打算使用Groovy++加速一下,发现一些代码有问题:
long a = 0
1000.times { int b->
a+=b
}
都过不了~
1.Groovy++编译时检查更严格
例1:
/* Leave it commented to run the dynamic Groovy version;
Uncomment to run Groovy++ version */
//@Typed
package test
def x = { List list ->
list.size()
}
x(1)
对Groovy,上述代码编译不会出错,但运行时会出错。因为我们调用的是x(Integer),而定义的是x(List)。
对Groovy++,编译时即报错:"Cannot find method { List -> ...}.doCall(int)"。
例2:
/* Commented -> dynamic Groovy version;
Uncommented -> Groovy++ version */
//@Typed
package test
class Foo {
def greet() {println "Foo says hello"}
}
class Bar {
def greet() {println "Bar says hello"}
}
def c = {greeter -> greeter.greet()}
c(new Foo())
c(new Bar())
对Groovy,得益于duck-typing,上述代码编译时和运行时都不会出错。
对Groovy++,则会出错:"Cannot find method Object.greet()" ,因为它会依照闭包参数的静态类型来做判断。
2.通过ExpandoMetaClass即时修改类型。
例3:
/* Commented -> dynamic Groovy version; Uncommented -> Groovy++ version */
//@Typed
package test
String.metaClass.foo = { -> println "foo called" }
"".foo() /* call my new method */
对Groovy,上述代码运行得很好,并动态给String增加foo方法。
对Groovy++,静态模式下不支持这一特性,“Mixed”模式可以解决这一问题,既享用动态特性,又保持静态检查。如下例所示
例4:
@Typed(TypePolicy.MIXED)
package test
String.metaClass.foo = { -> println "foo called" } // supported
"".foo()
3.Groovy++闭包更像是Java的内嵌类
在Java中,内嵌类不能引用其外部范围的非final成员。如下述代码编译将出错。
例5:
void foo(){
String data = "";
class Inner {
void innerFoo() {
System.out.println(data);
}
}
}
groovy把闭包看作是内嵌类,但是不限制对外部非final成员的访问,因此下属代码可以在Groovy中运行
例6:
void foo(){
String data = 'original';
def cl = {data = 'changed'} // access non-final data of its outer scope
cl()
assert data == 'changed'
}
foo()
Groovy++与Java更加接近,只允许以只读方式访问非final数据成员。如下例,如果试图修改这些成员,则会报 错:"Cannot modify final field test.Test$foo$1.data"
例7:
@Typed
package test
void foo(){
String data = 'original';
def cl = {data = 'changed'}
}
foo()
之所以这样,项目领导Alex Tkachman解释主要是避免并行运行风险。但如果不做并行运算,是否有什么解决之道?参见下例,用groovy.lang.Reference:
例8:
@Typed
package test
void foo(){
Reference data = ['original']
def cl = {data = 'changed'} // now even Groovy++ supports modification of non-final outer scope data
cl()
assert data == 'changed'
}
foo()
4.Groovy++不再直接访问私有成员
Groovy没有限制从外部访问一个类的私有成员,下例将正常运行。
例9:
/* Commented -> dynamic Groovy version; Uncommented -> Groovy++ version */
//@Typed
package test
class SecretService {
String secret = "secret"
String getSecret() {
"covered-" + secret
}
private launchOperation() {
"launched"
}
}
def ss = new SecretService()
assert ss.@secret == "secret" // can access the private field directly
assert ss.launchOperation() == "launched" // can access the private method
Groovy++ 则在编译时限制这种访问,对Groovy++,上面例子"ss.@secret" 会导致 "Cannot access field test.SecretService.secret"; "ss.launchOperation()" 会导致 "Cannot access method SecretService.launchOperation()"。
5.还有一些小的差别
例10:Script binding 变量
/* Commented -> dynamic Groovy version; Uncommented -> Groovy++ version */
//@Typed
package test
foo = "foo"
assert foo == "foo"
上述例子对Groovy没有问题,变量foo是在script中绑定的。但在Groovy++ 中不支持,如果要在Groovy中使用这一特性,得用@Typed(TypePolicy.MIXED)标注方式。
例11:对map的属性风格访问
/* Commented -> dynamic Groovy version; Uncommented -> Groovy++ version */
//@Typed
package test
def map = [key1: "value1"]
assert map.key1 == "value1"
map.key1这种方式访问map,对Groovy没问题,但 Groovy++不支持,除非用MIXED模式。
long a = 0
1000.times { int b->
a+=b
}
都过不了~
1.Groovy++编译时检查更严格
例1:
/* Leave it commented to run the dynamic Groovy version;
Uncomment to run Groovy++ version */
//@Typed
package test
def x = { List list ->
list.size()
}
x(1)
对Groovy,上述代码编译不会出错,但运行时会出错。因为我们调用的是x(Integer),而定义的是x(List)。
对Groovy++,编译时即报错:"Cannot find method { List -> ...}.doCall(int)"。
例2:
/* Commented -> dynamic Groovy version;
Uncommented -> Groovy++ version */
//@Typed
package test
class Foo {
def greet() {println "Foo says hello"}
}
class Bar {
def greet() {println "Bar says hello"}
}
def c = {greeter -> greeter.greet()}
c(new Foo())
c(new Bar())
对Groovy,得益于duck-typing,上述代码编译时和运行时都不会出错。
对Groovy++,则会出错:"Cannot find method Object.greet()" ,因为它会依照闭包参数的静态类型来做判断。
2.通过ExpandoMetaClass即时修改类型。
例3:
/* Commented -> dynamic Groovy version; Uncommented -> Groovy++ version */
//@Typed
package test
String.metaClass.foo = { -> println "foo called" }
"".foo() /* call my new method */
对Groovy,上述代码运行得很好,并动态给String增加foo方法。
对Groovy++,静态模式下不支持这一特性,“Mixed”模式可以解决这一问题,既享用动态特性,又保持静态检查。如下例所示
例4:
@Typed(TypePolicy.MIXED)
package test
String.metaClass.foo = { -> println "foo called" } // supported
"".foo()
3.Groovy++闭包更像是Java的内嵌类
在Java中,内嵌类不能引用其外部范围的非final成员。如下述代码编译将出错。
例5:
void foo(){
String data = "";
class Inner {
void innerFoo() {
System.out.println(data);
}
}
}
groovy把闭包看作是内嵌类,但是不限制对外部非final成员的访问,因此下属代码可以在Groovy中运行
例6:
void foo(){
String data = 'original';
def cl = {data = 'changed'} // access non-final data of its outer scope
cl()
assert data == 'changed'
}
foo()
Groovy++与Java更加接近,只允许以只读方式访问非final数据成员。如下例,如果试图修改这些成员,则会报 错:"Cannot modify final field test.Test$foo$1.data"
例7:
@Typed
package test
void foo(){
String data = 'original';
def cl = {data = 'changed'}
}
foo()
之所以这样,项目领导Alex Tkachman解释主要是避免并行运行风险。但如果不做并行运算,是否有什么解决之道?参见下例,用groovy.lang.Reference:
例8:
@Typed
package test
void foo(){
Reference data = ['original']
def cl = {data = 'changed'} // now even Groovy++ supports modification of non-final outer scope data
cl()
assert data == 'changed'
}
foo()
4.Groovy++不再直接访问私有成员
Groovy没有限制从外部访问一个类的私有成员,下例将正常运行。
例9:
/* Commented -> dynamic Groovy version; Uncommented -> Groovy++ version */
//@Typed
package test
class SecretService {
String secret = "secret"
String getSecret() {
"covered-" + secret
}
private launchOperation() {
"launched"
}
}
def ss = new SecretService()
assert ss.@secret == "secret" // can access the private field directly
assert ss.launchOperation() == "launched" // can access the private method
Groovy++ 则在编译时限制这种访问,对Groovy++,上面例子"ss.@secret" 会导致 "Cannot access field test.SecretService.secret"; "ss.launchOperation()" 会导致 "Cannot access method SecretService.launchOperation()"。
5.还有一些小的差别
例10:Script binding 变量
/* Commented -> dynamic Groovy version; Uncommented -> Groovy++ version */
//@Typed
package test
foo = "foo"
assert foo == "foo"
上述例子对Groovy没有问题,变量foo是在script中绑定的。但在Groovy++ 中不支持,如果要在Groovy中使用这一特性,得用@Typed(TypePolicy.MIXED)标注方式。
例11:对map的属性风格访问
/* Commented -> dynamic Groovy version; Uncommented -> Groovy++ version */
//@Typed
package test
def map = [key1: "value1"]
assert map.key1 == "value1"
map.key1这种方式访问map,对Groovy没问题,但 Groovy++不支持,除非用MIXED模式。
相关文章推荐
- 在使用easyui的时候有哪些需要注意的点?
- 公司开发时候,使用svn进行版本控制,在提交代码的时候应该注意的问题,总结!!!!
- java在使用实现了List接口时候应该注意的问题
- 【学习笔记】汇编:关于DEBUG工具使用的时候的一个注意事项
- 关于在使用babylon导入外部模型的时候要注意的事项
- Spring使用事务的时候需要注意的地方
- Android 从具体实例分析Bitmap使用时候内存注意点
- 包含别人的dll,然后我们用类库再次封装成dll的时候的注意事项;源文件与模块生成时的文件不同;创建调试信息文件 ··PDB时发生意外的错误,进程无法访问文件,因为另一个程序正在使用此文件
- DB2数据库中SQL语句中使用or和and的关键字的时候注意事项
- Spring 使用其他命名空间的时候要注意的事项
- vue项目使用cli手脚架搭建的时候要开发的步骤和注意事项
- PHP在使用正则表达式验证,防注入的时候要注意一下的细节
- 使用py-solc时候应该注意的问题
- ASP.NET使用三层架构时候注意的问题+基础使用
- BBOSS框架使用jquery方式传参到后台的时候,要注意的事项
- myfaces使用时候注意的小问题。
- [Sencha ExtJS & Touch] 表格(Ext.grid.Grid) 和 表格视图选项(Ext.grid.plugin.ViewOptions) 使用的时候要注意的问题
- 在使用service测试类的时候需要在控制台中打印信息提示,然后在进行controller层进行使用需要注意事项
- fftw使用时候需注意的内容
- nrf51822在使用Timer1和Timer2定时器的时候如何设置定时注意地方