ranges
尽管ranges没有出现在java标准类库中,但大多数程序员对range都有一个直观的概念--一个有效的开始点和一个结束点,类似于for语句
范 围 是一系列的值。例如 “0..4” 表明包含 整数 0、1、2、3、4。Groovy 还支持排除范围,“0..<4” 表示 0、1、2、3。还可以创建字符范围:“a..e” 相当于 a、b、c、d、e。“a..<e” 包括小于 e 的所有值。
循环范围
范围为循环带来了很大的方便。例如,前面从 0 递增到 4 的 for 循环如下所示:
for(i = 0; i < 5; i++)
范围可以将这个 for 循环变得更简洁,更易阅读:
def repeat(val){
for(i in 0..5){
println val
}
}
设置范围
如果运行这个示例,可能会注意到一个小问题:“Hello World” 输出了六次而不是五次。这个问题有三种解决方法:
将包含的范围限制到 4:
for(i in 0..4)
从 1 而不是 0 开始:
def repeat(val){
for(i in 1..5){
println val
}
}
将范围由包含改为排除:
def repeat(val){
for(i in 0..<5){
println val
}
}
不论采用哪种方法,都会得到原来的效果 — 输出五次。
默认参数值
现 在已经成功地使用 Groovy 的范围表达式缩短了 repeat 函数。但这个函数依然有些限制。如果想重复 “Hello World” 八次该怎么办?如果想对不同的值重复不同次数 — 比如 “Hello World” 重复八次,“Goodbye Sunshine” 重复两次,这时该怎么办?
每次调用 repeat 时都要指定需要的重复次数的做法已经过时了,特别是在已经适应了默认行为(重复五次)的时候。
Groovy 支持默认参数值,可以在函数或方法的正式定义中指定参数的默认值。调用函数的程序可以选择省略参数,使用默认值。
更加复杂的参数值
使用前面的 repeat 函数时,如果希望调用程序能够指定重复值,可以像下面这样编码:
def repeat(val, repeat=5){
for(i in 0..<repeat){
println val
}
}
像下面这样调用该函数:
repeat("Hello World", 2)
repeat("Goodbye sunshine", 4)
repeat("foo")
结果会输出 “Hello World” 两次,“Goodbye sunshine” 四次,“foo” 五次(默认次数)。
事实上,range可以使用任何类型,只要这个类型满足一下两个条件:
- 该类型实现立刻next和previous方法,也就是说,重写++和--操作符
- 该类实现java.lang.Comparable接口,也就是说实现compareTo方法,实际上重写<=>操作符
class Weekday implements Comparable{
static final DAYS=['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
private int index=0
Weekday(String day){
index=DAYS.indexOf(day)
}
Weekday next(){
return new Weekday(DAYS[(index+1)%DAYS.size()])
}
Weekday previous(){
return new Weekday(DAYS[(index-1)])
}
int compareTo(java.lang.Object other){
return this.index <=> other.index
}
String toString(){
return DAYS[index]
}
}
def mon=new Weekday('Mon')
def fri= new Weekday('Fri')
for(day in mon..fri){
println day
}
=========================================
Mon
Tue
Wed
Thu
Fri