集合
(1)List (java.util.List)
List = [1,2,'hello',new java.util.Date()]
assert List.size() == 4
assert List.get(2) == 'hello'
注意:一切都是对象(数字会自动转换)
(2)Map (java.util.Map)
map = ['name':'James','location':'London']
assert map.size() == 2
assert map.get('name') == 'James'
(3)遍历集合
List = [1,3]
for (i in List) { println i }
2、 闭包(Closures)
l 闭包类似Java的内类,区别是闭包只有单一的方法可以调用,但可以有任意的参数
closure = { param -> println("hello ${param}") }
closure.call("world!")
closure = { greeting,name -> println(greeting + name) }
closure.call("hello ","world!")
l 闭包用“{}”括起,“->”前面是参数,后面是处理语句,使用call调用
l 第一个例子演示了在字符串内使用参数的形式:${param}
l 第二个例子演示了多参数形式:用“,”分隔参数
l 如果只有一个参数,可以不写,而使用缺省的参数“it”,如下面的例子:
closure = { println "hello " + it }
closure.call("world!")
3、 each
l 遍历集合,逐个传递给闭包
[1,3].each { item -> print "${item}-" }
l 上面例子的输出结果是:1-2-3-
4、 collect
l 遍历集合,逐个传递给闭包,处理后的结果返回给对应的项
value = [1,3].collect { it * 2 }
assert value == [2,4,6]
与each区别:
value2 = [1,3].each { it * 2 }
println value2
value3 = [1,3].collect { it * 2 }
println value3
结果:
[1,3]
[2,6]
返回值不同
5、 find
l 根据闭包断言,返回集合中找到的第一个项目
value = [1,3].find { it > 1 }
assert value == 2
6、 findAll
l 根据闭包断言,返回集合中所有找到的项目
value = [1,3].findAll { it > 1 }
assert value == [2,3]
7、 inject
l 遍历集合,第一次将传递的值和集合项目传给闭包,将处理结果作为传递的值,和下一个集合项目传给闭包,依此类推
value = [1,3].inject('counting: ') { str,item -> str + item }
assert value == "counting: 123"
value = [1,3].inject(0) { count,item -> count + item }
assert value == 6
8、 every
l 如果集合中所有项目都匹配闭包断言,就返回true,否则返回false
value = [1,3].every { it < 5 }
assert value
value = [1,3].every { item -> item < 3 }
assert ! value
9、 any
l 如果集合中任何项目匹配闭包断言,就返回true,否则返回false
value = [1,3].any { it > 2 }
assert value
value = [1,3].any { item | item > 3 }
assert value == false
10、 min/max
l 返回集合中的最小/最大项目(对象必须可比较)
value = [9,10,5].max()
assert value == 10
value = [9,5].min()
assert value == 2
value = ['x','y','a','z'].min()
assert value == 'a'
11、 join
l 连接集合中的值成一个字符串
value = [1,3].join('-')
assert value == '1-2-3'
12、 yIEld
l 在Python和Ruby中通过yIEld语句创建“yIEld”风格的iterators,在Groovy同样有效,只是使用的是闭包
class Foo{
static voID main(args) {
foo = new Foo()
for (x in foo.myGenerator) {
print("${x}-")
}
}
myGenerator(Closure yIEld) {
yIEld.call("A")
yIEld.call("B")
yIEld.call("C")
}
}
l 例子的输出结果是:A-B-C-
l Cloures原型可以省略,call和括号同样可选,这样更象Python/Ruby
class Foo {
myGenerator(yIEld) {
yIEld "A"
yIEld "B"
yIEld "C"
}
static voID main(args) {
foo = new Foo()
foo.myGenerator { println "Called with ${it}" }
}
}
1.闭包
先解释一下闭包的概念:
闭包是很多动态语言提供的一个很方便的功能,它有点像Java中的内部类,
不同的是闭包中只有一个方法,但这个方法可以有任意个参数。
下面看一个闭包的最简单的例子:
def closure={ param -> println "hello${param}" }
closure.call("world!")
def是一个关键字,相当于JavaScript中的Var,用来定义一个对象。
closure为闭包的名字。在大括号里面,参数和处理参数的语句用->隔开。
param是这个闭包的参数,参数的数目是任意的,不同的参数之间用","隔开。
下面处理这些参数的语句就可以直接调用这些参数了。
所有的闭包都是继承自groovy.lang.Closure类,闭包也是一个普通的类,
只是在Groovy中,这个语法比较特别。所以闭包也可以当作一个返回值。
或者当作一个参数传入一个方法。
闭包的返回值:
调用闭包的call方法,会有一个返回值,可以调用return来指定,如果不指定的话,
则返回闭包中最后一条有返回值的语句。
闭包可以调用的对象:
在方法里面,可以调用方法内的局部变量
作为类变量,可以调用类变量
关于0个参数以及对象it:
参数可以是任意个,没有参数就不需要"->"了。没有参数的话,但是传入了一个参数,
这个参数可以通过一个无类型的对象"it"来访问。比如上面的例子我们可以这么写:
def closure2={ println "hello ${it}"}
closure2.call("world!")
关于闭包的调用:
定义以后就可以调用这个闭包,有两种方式,
closure.call("world!")
closure("world!")
这两种是没有任何区别的,第二个是第一个的简写
2.集合的本地化语法
这个比闭包更容易理解,Groovy对collections,Lists,maps,arrays的声明和使用
提供了语言级的支持,可以直接声明一个List和map,无需调用new方法创建一个List或者
map对象。
看一个来自Groovy官方网站的例子:
def List = [5,6,7,8]
assert List.get(2) == 7
assert List[2] == 7
assert List instanceof java.util.List
def emptyList = []
assert emptyList.size() == 0
emptyList.add(5)
assert emptyList.size() == 1
与Java的区别如下:
1.通过[value...]的方式来声明
2.通过List[index]的方式来访问和赋值
3.通过[]来声明一个空的map
看一个Map的例子:
def map = [name:"Gromit",likes:"cheese",ID:1234]
assert map.get("name") == "Gromit"
assert map.get("ID") == 1234
assert map["name"] == "Gromit"
assert map['ID'] == 1234
assert map instanceof java.util.Map
def emptyMap = [:]
assert emptyMap.size() == 0
emptyMap.put("foo",5)
assert emptyMap.size() == 1
assert emptyMap.get("foo") == 5
与Java的区别如下:
1.通过[name:value...]的方式来声明
2.通过map[name]的方式来访问和赋值
3.通过map.name的方式来访问和赋值
4.通过[:]来声明一个空的map
Range的使用:
Range是Groovy新添的一个集合类,继承自java.util.List,所以可以像使用List一样使用。
下面是关于Range的一个例子:
def range = 5..8
assert range.size() == 4
assert range.get(2) == 7
assert range[2] == 7
assert range instanceof java.util.List
assert range.contains(5)
assert range.contains(8)
range = 5..<8
assert range.size() == 3
assert range.get(2) == 7
assert range[2] == 7
assert range instanceof java.util.List
assert range.contains(5)
assert ! range.contains(8)
几个说明
1.Range的类型可以是int、char
2.通过min..max来声明
3.可以像其他集合一样使用
'*.' *** 作符号的使用:
可以用来使集合中的所有元素都调用同一个方法,返回一个同等size的List
List List = ["Rod","Phil","James","Chris"]
println List*.size()
String的特殊使用:
String在Groovy中可以像char数组一样的使用,下面是一个例子:
def text = "nice cheese gromit!"
def x = text[2]
assert x == "c"
assert x.class == String
def sub = text[5..10]
assert sub == 'cheese'
说明:
1.通过text[index]的方式返回在index处的字符,不过返回的是string类型的,非char类型
2.通过text[min..max]方式来返回子字符串,包含max处的字符,String的subString不包含。
3.从这个例子中可以看到,可以使用'string'来表示String,不一定是"string"
---------------------------------------------------------------------------------
--------------------------------------------------------------------------------
1、类
(1)类
l Groovy的类定义和java类似
Ø 方法可以基于类(static)或实例
Ø 可以为public、protected或private
Ø 支持常用的Java修饰符,如synchronized
l Groovy的不同地方:缺省是public
l Groovy支持JavaBean机制:GroovyBean
l 每个Groovy类都是字节码/JVM级的java类,任何方法对Java都是有效的,反之亦然
l 你可以指定方法的参数类型和返回类型,这样可以在通常的Java代码中更好的工作
l 你可以用上面的方式来实现接口或重载方法
l 如果省略方法的类型,就会使用缺省的java.lang.Object
(2)脚本
l Groovy支持纯脚本,而不需要声明类,如Foo.groovy包含下面的脚本:
println "Nice cheese Gromit!"
l 运行脚本的过程:
Ø 编译成Foo.class(还会有一些内类),该类扩展groovy.lang.Script
Ø 执行自动生成的main方法
Ø 实例化Foo类
Ø 调用run方法执行脚本内容
l 可以在Java代码中执行脚本,同时还可以传递变量值到脚本中
l Foo.groovy内容修改如下
println "Nice ${cheese} Gromit!"
l 下面是执行脚本的UseFoo类
import groovy.lang.Binding;
import groovy.lang.Script;
public class UseFoo {
public static voID main(String[] args) {
Binding binding = new Binding();
binding.setvariable("cheese","Cheddar");
Script foo = new Foo(binding);
foo.run();
}
}
l UseFoo运行的结果是:Nice Cheddar Gromit!
l 执行脚本的方法是创建Foo类实例,调用其run方法
l Foo类有一个带Binding参数的构造函数,可以通过Binding类的setvariable方法设置值给脚本中的属性变量
l Foo类有一个不带参数的构造函数,在不传递属性变量值时使用
l 在脚本结束后,脚本中创建的任何变量都会在Binding中,以供在Java中访问
l 再将Foo.groovy内容修改如下
println "Nice ${cheese} Gromit!"
cheese = "changed"
l UseFoo类修改为:
import groovy.lang.Binding;
import groovy.lang.Script;
public class UseFoo {
public static voID main(String[] args) {
Binding binding = new Binding();
binding.setvariable("cheese","Cheddar");
Script foo = new Foo(binding);
foo.run();
println binding.getvariable("cheese");
}
}
l UseFoo运行的结果是:
Nice Cheddar Gromit!
changed
(3)脚本中的函数
l 不同于基于Class的Groovy,纯脚本中的函数用def关键字声明
def foo(List,value) {
println "Calling function foo() with param ${value}"
List << value
}
x = []
foo(x,1)
foo(x,2)
assert x == [1,2]
println "Creating List ${x}"
2、闭包
(1)概述
l 闭包是一种传递执行代码块的强大方法。
l 可以把闭包看作Java中的匿名内类,但是只有单一的(匿名)方法。
l 闭包可以被用作循环的一种替代方法
[1,3,4].each { println(it) }
l 使用闭包可以使异常处理和关闭资源变得更简单,具体例子请参看Groovy sql
(2)比较闭包和匿名内类
l 不同于Java匿名内类,Groovy 支持“true closures”:状态可以被传递到闭包外部
l 局部变量在闭包创建时可以被使用和修改;闭包中创建的任何变量可以作为局部变量,对外部可见
l 看下面的例子:
count = 0
last = 0
[1,4].each { count += it; last = it }
println("the sum is ${count} and the last item was ${last}")
输出结果:the sum is 10 and the last item was 4
(3)闭包是普通对象
l 闭包是在需要时被传递和调用的对象
l 因此可以象下面一样使用:
c = { println("Hello ${it}") }
c.call('James')
c.call('Bob')
l 闭包会被编译成扩展groovy.lang.Closure类的新类
l 下面的省略写法是等价的
c = { println("Hello ${it}") }
c('James')
c('Bob')
(4)闭包的参数
l 闭包可以有任意数目的参数
l 缺省情况,闭包具有单个缺省参数:“it”
l 你可以在闭包声明的开始部分指定参数列表
c = { a,b,c –> println("Hello ${a} ${b} ${c}") }
c('cheese',234,'gromit')
l 下面是另一个使用两个参数的有用例子,在《Groovy快速入门》已经讲过:
value = [1,item –> str + item }
assert value == "counting: 123"
value = [1,item -> count + item }
assert value == 6
3、集合
Groovy支持集合、List、Map和数组
(1)Lists
l 下面是创建List的例子,[]表示空List表达式
List = [5,8]
assert List.get(2) == 7
assert List instanceof java.util.List
emptyList = []
assert emptyList.size() == 0
emptyList.add(5)
assert emptyList.size() == 1
l 每个List表达式都是java.util.List的实现
(2)范围(Ranges)
l Range允许创建连续值的列表
l 由于Range扩展java.util.List,所以Range可以作为List使用
l 使用..的Range是包括两个边界,使用...的Range只包括开始边界,而不包括结束边界(//我在groovy1.5中不能使用...,如果想建立不包括边界的范围,可以使用 range=5..<8)
// an inclusive range
range = 5..8
assert range.size() == 4
assert range.get(2) == 7
assert range instanceof java.util.List
assert range.contains(5)
assert range.contains(8)
// lets use an exclusive range
range = 5...8
assert range.size() == 3
assert range.get(2) == 7
assert range instanceof java.util.List
assert range.contains(5)
assert ! range.contains(8)
//我在groovy1.5中不能使用...,如果想建立不包括边界的范围,可以使用如下
range=5..<8
l Range可以用于实现java.lang.Comparable的Java对象
// an inclusive range
range = 'a'..'d'
assert range.size() == 4
assert range.get(2) == 'c'
assert range instanceof java.util.List
assert range.contains('a')
assert range.contains('d')
assert ! range.contains('e')
l Range可以用于循环遍历
for (i in 1..10) {
println "Hello ${i}"
}
(3)Maps
l 下面是创建Map的例子,[:]表示空Map表达式
map = ["name":"Gromit","likes":"cheese","ID":1234]
assert map.get("name") == "Gromit"
assert map.get("ID") == 1234
assert map instanceof java.util.Map
emptyMap = [:]
assert emptyMap.size() == 0
emptyMap.put(5,"foo")
assert emptyMap.size() == 1
assert emptyMap.get(5) == "foo"
l Map可以象beans一样 *** 作,但key值(类似属性名)必须为有效的String标识
map = ["name":"Gromit","ID":1234]
assert map.name == "Gromit"
assert map.ID == 1234
emptyMap = [:]
assert emptyMap.size() == 0
emptyMap.foo = 5
assert emptyMap.size() == 1
assert emptyMap.foo == 5
(4)使用下标 *** 作符
l 可以在字符串、Lists、Maps...中使用下标进行索引
text = "nice cheese gromit!"
x = text[2]
assert x == "c"
assert x.class == String
sub = text[5..10]
assert sub == 'cheese'
map = ["name":"Gromit","ID":1234]
assert map['name'] == "Gromit"
List = [10,11,12]
answer = List[2]
assert answer == 12
List = 100..200
sub = List[1,20..25,33]
assert sub == [101,103,120,121,122,123,124,125,133]
l 可以使用下标 *** 作符更新项目
List = ["a","b","c"]
List[2] = "d"
List[0] = List[1]
List[3] = 5
assert List == ["b","d",5]
l 可以使用负索引从最后开始计数
text = "nice cheese gromit!"
x = text[-1]
assert x == "!"
name = text[-7..-2]
assert name == "gromit"
l 也可以使用向后范围(开始索引大于结束索引),返回的结果是反转的
text = "nice cheese gromit!"
name = text[3..1]
assert name == "eci"
4、与Java的不同
(1)通用
l 在Groovy中,==等价于equals(),===意味着标识比较(等同Java中的==)好像没有这个 *** 作符===
l 在Java中==意味着原类型的相等和对象的标识比较,如a==b(a和b是指向相同对象的引用)
l 传递闭包给方法或使用GroovyMarkup时,{要和方法的调用在同一行上,如:(本人尝试不在同一行也可,但建议遵守要求)
[1,3].each { println it }
l 如果要将{放在独立于方法的一行上,要使用括号()
[1,3].each (
{ println it }
)
l 下面的写法是无效的,会将闭包解释成独立的闭包,而不会将闭包作为方法的参数传递
[1,3].each
{
println it
}
(2)应该意识到的事情
l 语句后面的分号是可选的,但在同一行上有多个语句需要用分号分隔
l return关键字可选
l 可以在static方法内使用_this_关键字(何用?)
l 缺省的修饰符是public
l Groovy中的protected等价包的protected和Java的protected
l 补充:方法调用时,括号是可选的,(注意最好使用括号,以防止错误)
(3)在Java中无效的Groovy新特性
l 闭包
l List和Map的本地语法
l GroovyMarkup和Gpath的支持
l 正则表达式的本地支持
l 多形式的iteration和强大的switch语句
l 动态和静态类型的支持
l 在字符串中嵌入表达式
l 增加了许多新的帮助方法
l 在属性和添加事件侦听方面,简化了编写bean的语法
5、Groovy Math
l Groovy支持访问所有的Java Math类和 *** 作
l 为了使math *** 作在脚本编写时尽可能直观,Groovymath模型支持文字化math *** 作
l 缺省计算使用的是精确的小数(BigDecimal),如:
1.1 + 0.1== 1.2
返回的是true,而不是false(不象在Java中使用float或double)
(1)数字的文字表示
l Groovy的小数文字表示是java.math.BigDecimal的实例,而不是浮点类型(float或Double)
l float和Double可以使用后面讲的后缀(F和D)方法来创建
l 小数的指数形式也支持,如12.3e-23
l 十六进制和八进制也支持,十六进制前缀0x,八进制前缀0
l 整数类型可以使用后面讲的后缀(I、L和G)方法来创建,如果不指定根据数值的大小使用合适的类型
l 数字类型的后缀文字表示
_Type_ | _Suffix_ |
_BigInteger_ | G |
_Long_ | L |
_Integer_ | I |
_BigDecimal_ | (缺省) |
_Double_ | D |
_float_ | F |
l 例子:
assert42I == new Integer("42");
assert123L == new Long("123");
assert2147483648 == new Long("2147483648"); //Long type used,valuetoo large for an Integer
assert456G == new java.math.BigInteger("456");
assert123.45 == new java.math.BigDecimal("123.45"); //default BigDecimaltype used
assert1.200065D == new Double("1.200065");
assert1.234F == new float("1.234");
assert1.23E23D == new Double("1.23E23");
(2)Math *** 作
l Groovy的Math实现很接近Java 1.5 BigDecimal Math模型的实践
l java.lang.Number包括其子类的二元 *** 作(除了除法)会根据下表自动转换参数类型
| _BigDecimal_ | _BigInteger_ | _Double_ | _float_ | _Long_ | _Integer_ |
_BigDecimal_ | BigDecimal | BigDecimal | Double | Double | BigDecimal | BigDecimal |
_BigInteger_ | BigDecimal | BigInteger | Double | Double | BigInteger | BigInteger |
_Double_ | Double | Double | Double | Double | Double | Double |
_float_ | Double | Double | Double | Double | Double | Double |
_Long_ | BigDecimal | BigInteger | Double | Double | Long | Long |
_Integer_ | BigDecimal | BigInteger | Double | Double | Long | Integer |
l 注意:Byte、Character、Short都作为Integer类型
(3)除法
l 除法 *** 作“/”和“/=”在 *** 作数中有float或Double类型时,结果为Double类型;其它情况,结果为BigDecimal类型
l BigDecimal类型的 *** 作会这样做:
BigDecimal.divIDe(BigDecimalright,<scale>,BigDecimal.ROUND_HALF_UP)
其中<scale>是MAX(this.scale(),right.scale(),10)
l 例子:
1/2 ==new java.math.BigDecimal("0.5");
1/3 ==new java.math.BigDecimal("0.3333333333");
2/3 ==new java.math.BigDecimal("0.6666666667");
l 整型除法使用“\”和“\=” *** 作,返回整型类型
l 由于“\”是Java中的转义符,在字符串中使用需要转义
" x= 8\3 "
(4)数字文字表示语法
Integerliteral:
Base10Integerliteral
HexIntegerliteral
Octalintegerliteral
Base10Integerliteral:
Base10Numeral IntegerTypeSuffix(optional)
HexIntegerliteral:
Hexnumeral IntegerTypeSuffix(optional)
Octalintegerliteral:
OctalNumeral IntegerTypeSuffix(optional)
IntegerTypeSuffix: one of
i I l L g G
Base10Numeral:
0
NonZeroDigit Digits (optional)
Digits:
Digit
Digits Digit
Digit:
0
NonZeroDigit
NonZeroDigit:one of
\1 2 3 4 5 6 7 8 9
Hexnumeral:
0 x HexDigits
0 X HexDigits
HexDigits:
HexDigit
HexDigit HexDigits
HexDigit:one of
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D EF
OctalNumeral:
0 OctalDigits
OctalDigits:
OctalDigit
OctalDigit OctalDigits
OctalDigit: one of
0 1 2 3 4 5 6 7
DecimalPointliteral:
Digits . Digits ExponentPart (optional)DecimalTypeSuffix (optional)
. Digits ExponentPart (optional)DecimalTypeSuffix (optional)
Digits ExponentPart DecimalTypeSuffix(optional)
Digits ExponentPart (optional)DecimalTypeSuffix (optional)
ExponentPart:
ExponentIndicator SignedInteger
ExponentIndicator:one of
e E
SignedInteger:
Signopt Digits
Sign: oneof
+ -
DecimalTypeSuffix:one of
f F d D g G
6、I/O
l Groovy提供许多有用的方法来处理I/O,包括标准的Java Reader/Writer、inputStream/OutputStream、file和URL类
l 使用闭包允许处理资源时确保正确关闭而不管是否有异常,例如下面的例子遍历文件的每一行,即使闭包中发生异常,文件也能正确关闭:
import java.io.file
new file("foo.txt").eachline { println it }
l 使用Reader/Writer:通过闭包处理资源
import java.io.file
new file("foo.txt").withReader { reader ->
while (true) {
line = reader.readline()
...
}
}
l Groovy提供简单的方法执行命令行进程,表达式返回java.lang.Process实例,具有in/out/err流(译者:没有测试过)
process = "ls -l".execute()
process.in.eachline { line | println line }
7、逻辑分支
(1)if-else语句
l Groovy提供Java相同的if-else语句
x = false
y = false
if ( !x ) {
x = true
}
assert x == true
if ( x ) {
x = false
} else {
y = true
}
assert x == y
l Groovy也支持三元 *** 作符
y = 5
x = (y > 1) ? "worked" : "Failed"
assert x == "worked"
(2)switch语句
l Groovy的switch语句兼容Java代码,不同之处在于Groovy的switch语句能够处理各种类型的switch值,可以做各种类型的匹配:类名,正则,集合,值。
Ø case值为类名匹配switch值为类实例,可为变量,动态
Ø case值为正则表达式匹配switch值的字符串匹配该正则表达式
Ø case值为集合匹配switch值包含在集合中,这包括ranges
Ø 除了上面的,case值与switch值相等才匹配
x = 1.23
result = ""
switch ( x ) {
case "foo":
result = "found foo"
case "bar":
result += "bar"
case [4,5,'inList']:
result = "List"
break
case 12..30:
result = "range"
break
case Integer:
result = "integer"
break
case Number:
result = "number"
break
default:
result = "default"
}
assert result == "number"
l switch语句的工作原理:switch语句在做匹配case值时调用isCase(switchValue)方法,缺省调用equals(switchValue),但是已经被重载成各种类型,如类,正则表达式、集合等等
l 可以创建自定义的匹配类,增加isCase(switchValue)方法来提供自定义的匹配类型
8、循环
(1)while和do 循环
l Groovy支持Java相同的while和do 循环
x = 0
y = 5
while ( y-- > 0 ) {
x++
}
assert x == 5
//个人测试不支持do..while语句
x = 0
y = 5
do {
x++
}
while ( --y > 0 )
assert x == 5
(2)for循环
l Groovy的for循环更简单,而且能够和各种类型的数组、集合、Map等一起工作
// iterate over a range
x = 0
for ( i in 0..9 ) {
x += i
}
assert x == 45
// iterate over a List
x = 0
for ( i in [0,1,4] ) {
x += i
}
assert x == 10
// iterate over an array
array = (0..4).toArray()
x = 0
for ( i in array ) {
x += i
}
assert x == 10
// iterate over a map
map = ['abc':1,'def':2,'xyz':3]
x = 0
for ( e in map ) {
x += e.value
}
assert x == 6
// iterate over values in a map
x = 0
for ( v in map.values() ) {
x += v
}
assert x == 6
// iterate over the characters in a string
text = "abc"
List = []
for (c in text) {
List.add(c)
}
assert List == ["a","c"]
9、 *** 作符重载
l Groovy支持 *** 作符重载,使得数值、集合、Map和其它种类的数据结构更容易使用
l 在Groovy中的各种 *** 作符被映射到对象中调用的正规方法
Operator | Method |
a + b | a.plus(b) |
a - b | a.minus(b) |
a * b | a.multiply(b) |
a / b | a.divIDe(b) |
a++ or ++a | a.next() |
a-- or --a | a.prevIoUs() |
a[b] | a.getAt(b) |
a[b] = c | a.putAt(b,c) |
a << b | a.leftShift(b) |
a == b | a.equals(b) |
a != b | ! a.equals(b) |
a === b | Java中的 a == b 好像没有这个 *** 作符 |
a <=> b | a.compareto(b) |
a > b | a.compareto(b) > 0 |
a >= b | a.compareto(b) >= 0 |
a < b | a.compareto(b) < 0 |
a <= b | a.compareto(b) <= 0 |
l 注意:所有比较 *** 作符已经对null处理了,以避免抛出java.lang.NullPointerException
a = null
b ="foo"
assert a!= b
assert b!= a
assert a== null
l 在不同类型的数值比较之前,Groovy会自动将数值的类型转换为更大范围的数值类型,因此,下面的例子是有效的:
Byte a =12
Double b= 10
assert ainstanceof Byte
assert binstanceof Double
assert a> b
10、正则表达式
l Groovy支持使用~”...”本地表示的正则表达式,另外还支持“=~” *** 作符(创建Matcher)
import java.util.regex.Matcher
import java.util.regex.Pattern
// same as assert ("cheesecheese" =~ "cheese").find()
assert "cheesecheese" =~ "cheese"
// lets create a regex Pattern
pattern = ~"a*b"
assert pattern instanceof Pattern
assert pattern.matcher("aaaab").matches()
// lets create a Matcher
matcher = "cheesecheese" =~ "cheese"
assert matcher instanceof Matcher
answer = matcher.replaceAll("edam")
assert answer == "edamedam"
l Matcher缺省会调用find()方法返回boolean值,因此可以使用=~与Perl的=~ *** 作符的简单使用保持一致
l 对于上面的模式匹配的例子主要是演示Pattern的用法,其实可以简化为
assert ("aaaab" =~ "a*b").matches()
11、语句
(1)分号
l Groovy使用类似Java的语法,但是语句的分号是可选的
l 如果每行一个语句,就可以省略分号;如果一行上有多个语句,就要用分号来分隔
x = [1,3]
println x
y = 5; x = y + 7
println x
assert x == 12
l 一个语句可以跨越多行,对于方法的参数列表或复杂的表达式,可能会这样做
x = [1,
4,6]
println(
x
)
if (x != null &&
x.size() > 5) {
println("Works!")
} else {
assert false: "should never happen ${x}"
}
(2)方法调用
l 方法调用的语法和Java类似,支持静态和实例方法
class Foo {
calculatePrice() {
1.23
}
static voID main(args) {
foo = new Foo()
p = foo.calculatePrice()
assert p > 0
println "Found price: " + p
}
}
l 注意,return关键字在方法的最后是可选的;同样,返回类型也是可选(缺省是Object)
l 在Groovy中方法的调用可以省略括号,只要有参数,并且没有歧义
(3)传递命名参数
l 在调用方法时,可以传递命名参数,参数的名字和值用分号分隔(象Map语法),参数名是唯一标识字符串
bean = new Expando(name:"James",location:"London",ID:123)
println "hey " + bean.name
assert bean.ID == 123
l 当前这种方法传递只实现具有Map的方法调用或JavaBean构造
(4)传递闭包给方法
请参考《Groovy快速入门》
(5)动态方法分派
l 如果变量没有使用类型强制,动态方法分派被使用,这经常被指为动态类型,而Java缺省使用静态类型
l 可以在代码中混合使用动态和静态类型
dynamicObject = "hello world".replaceAll("world","Gromit")
dynamicObject += "!"
assert dynamicObject == "hello Gromit!"
String staticObject = "hello there"
staticObject += "!"
assert staticObject == "hello there!"
(6)属性
l 通过“.属性名”访问属性
bean = new Expando(name:"James",ID:123)
name = bean.name
println("hey ${name}")
bean.location = "Vegas"
println bean.name + " is Now in " + bean.location
assert bean.location == "Vegas"
l 上面的特殊bean Expando在运行时,动态添加属性
l 它实际上是一个行为象动态bean的Map:增加name/value对和等效的getter/setter方法,就象定义一个真正的bean
(7)安全导航
l 如果你在访问复杂对象时,不想遇到NullPointerException异常,你可以使用“->”而不是“.”来导航
foo = null
bar = foo->something->myMethod()
assert bar == null
总结 以上是内存溢出为你收集整理的groovy用户指南全部内容,希望文章能够帮你解决groovy用户指南所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)