groovy用户指南

groovy用户指南,第1张

概述     集合 (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', 'lo

     集合

(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.可以像其他集合一样使用

'*.' *** 作符号的使用:
可以用来使集合中的所有元素都调用同一个方法,返回一个同等sizeList
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用户指南所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1266205.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存