在本篇文章中,我们将介绍逻辑分支,循环,以及如何从if-else以及try-catch代码块中返回值。
if – else
Groovy 支持Java传统的if-else语法:
def x = false def y = false if ( !x ) {
x = true
} assert x == true if ( x ) {
x = false
} else {
y = true
} assert x == y
Groovy 也支持Java传统的if-else if -else 语法:
1 |
if ( ... ) {
|
2 |
... |
3 |
} else if (...) {
|
4 |
... |
5 |
} else {
|
6 |
... |
7 |
} |
三元操作符
Groovy 也支持Java传统的三元操作符:
1 |
def y = 5
|
2 |
def x = (y > 1 ) ? "worked" : "failed"
|
3 |
assert x == "worked"
|
switch
Groovy也支持switch语句,不过和java的switch语句还是有很大的区别的:
1 |
def x = 1.23
|
2 |
def result = ""
|
3 |
4 |
switch ( x ) {
|
5 |
case "foo" :
|
6 |
result = "found foo"
|
7 |
// lets fall through
|
8 |
9 |
case "bar" :
|
10 |
result += "bar"
|
11 |
12 |
case [ 4 , 5 , 6 , 'inList' ]:
|
13 |
result = "list"
|
14 |
break
|
15 |
16 |
case 12 .. 30 :
|
17 |
result = "range"
|
18 |
break
|
19 |
20 |
case Integer:
|
21 |
result = "integer"
|
22 |
break
|
23 |
24 |
case Number:
|
25 |
result = "number"
|
26 |
break
|
27 |
28 |
default :
|
29 |
result = "default"
|
30 |
} |
31 |
32 |
assert result == "number"
|
从上面的例子可以看出switch ( x )中的x可以使用任何类型的值,而且下面的匹配值也可以使用任何的类型。
循环
Groovy也支持Java传统的while循环语法:
1 |
def x = 0
|
2 |
def y = 5
|
3 |
4 |
while ( y-- > 0 ) {
|
5 |
x++
|
6 |
} |
7 |
8 |
assert x == 5
|
for循环
在Groovy中,for循环更加的简单,而且如果你愿意的话,你也可以在Groovy中使用标准的C/Java的for循环语法。
1 |
for ( int i = 0 ; i < 5 ; i++) {
|
2 |
} |
3 |
4 |
// iterate over a range |
5 |
def x = 0
|
6 |
for ( i in 0 .. 9 ) {
|
7 |
x += i
|
8 |
} |
9 |
assert x == 45
|
10 |
11 |
// iterate over a list |
12 |
x = 0
|
13 |
for ( i in [ 0 , 1 , 2 , 3 , 4 ] ) {
|
14 |
x += i
|
15 |
} |
16 |
assert x == 10
|
17 |
18 |
// iterate over an array |
19 |
array = ( 0 .. 4 ).toArray()
|
20 |
x = 0
|
21 |
for ( i in array ) {
|
22 |
x += i
|
23 |
} |
24 |
assert x == 10
|
25 |
26 |
// iterate over a map |
27 |
def map = [ 'abc' : 1 , 'def' : 2 , 'xyz' : 3 ]
|
28 |
x = 0
|
29 |
for ( e in map ) {
|
30 |
x += e.value
|
31 |
} |
32 |
assert x == 6
|
33 |
34 |
// iterate over values in a map |
35 |
x = 0
|
36 |
for ( v in map.values() ) {
|
37 |
x += v
|
38 |
} |
39 |
assert x == 6
|
40 |
41 |
// iterate over the characters in a string |
42 |
def text = "abc"
|
43 |
def list = []
|
44 |
for (c in text) {
|
45 |
list.add(c)
|
46 |
} |
47 |
assert list == [ "a" , "b" , "c" ]
|
闭包(closures)
有时候你也可以使用闭包的each()和eachWithIndex()方法来替换一些for循环代码。
1 |
def stringList = [ "java" , "perl" , "python" , "ruby" , "c#" , "cobol" ,
|
2 |
"groovy" , "jython" , "smalltalk" , "prolog" , "m" , "yacc" ];
|
3 |
4 |
def stringMap = [ "Su" : "Sunday" , "Mo" : "Monday" , "Tu" : "Tuesday" ,
|
5 |
"We" : "Wednesday" , "Th" : "Thursday" , "Fr" : "Friday" ,
|
6 |
"Sa" : "Saturday" ];
|
7 |
8 |
stringList. each () { print " ${it}" }; println "" ;
|
9 |
// java perl python ruby c# cobol groovy jython smalltalk prolog m yacc |
10 |
11 |
stringMap. each () { key, value -> println "${key} == ${value}" };
|
12 |
// Su == Sunday |
13 |
// We == Wednesday |
14 |
// Mo == Monday |
15 |
// Sa == Saturday |
16 |
// Th == Thursday |
17 |
// Tu == Tuesday |
18 |
// Fr == Friday |
19 |
20 |
stringList. eachWithIndex () { obj, i -> println " ${i}: ${obj}" };
|
21 |
// 0: java |
22 |
// 1: perl |
23 |
// 2: python |
24 |
// 3: ruby |
25 |
// 4: c# |
26 |
// 5: cobol |
27 |
// 6: groovy |
28 |
// 7: jython |
29 |
// 8: smalltalk |
30 |
// 9: prolog |
31 |
// 10: m |
32 |
// 11: yacc |
33 |
34 |
stringMap. eachWithIndex () { obj, i -> println " ${i}: ${obj}" };
|
35 |
// 0: Su=Sunday |
36 |
// 1: We=Wednesday |
37 |
// 2: Mo=Monday |
38 |
// 3: Sa=Saturday |
39 |
// 4: Th=Thursday |
40 |
// 5: Tu=Tuesday |
41 |
// 6: Fr=Friday |
从if-else和try-catch代码块中返回值
从 Groovy 1.6开始,在方法或者闭包中的最后一行表达式,可以从if/else和try/catch/finally代码块中返回值,而且并不需要明确的使用return关键字返回值,只需要他们是代码块的最后一个表达式就行。
下面的例子就说明了这个情况,在下面的代码块中虽然没有显示的调用return关键字,但是仍然会返回1:
1 |
def method() {
|
2 |
if (true) 1 else 0
|
3 |
} |
4 |
5 |
assert method() == 1
|
对于 try/catch/finally blocks代码块来说,如果try代码块中没有抛出异常的话,那么try代码块的最后一行的表达式将会被返回,如果try的代码块抛出异常并且被catch住的时候,那么catch代码块中的最后一个表达式的值将会被返回。
但是请注意:finally代码块不会返回值的。
1 |
def method(bool) {
|
2 |
try {
|
3 |
if (bool) throw new Exception( "foo" )
|
4 |
1
|
5 |
} catch (e) {
|
6 |
2
|
7 |
} finally {
|
8 |
3
|
9 |
}
|
10 |
} |
11 |
12 |
assert method(false) == 1
|
13 |
assert method(true) == 2
|