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

groovy用户指南

发布时间:2020-12-14 16:53:01 所属栏目:大数据 来源:网络整理
导读:???? 集合 (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'] a

???? 集合

(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= 83 "

(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

(编辑:李大同)

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

    推荐文章
      热点阅读