我使用范围运算符在Groovy中编写了一个方法,以便多次执行相同的代码:
/**
* Prints the {@code files} {@code copyCount} times using
* {@code printService}.
* <p>
* Exceptions may be thrown.
* @param printService Print service
* @param files List of {@code File} objects
* @param copyCount Number of copies to print
*/
private static void printJob(
PrintService printService,
List<File> files,
int copyCount) {
// No multiple copy support for PS files, must do it manually
for ( i in 1..copyCount ) {
// Print files
}
}
此方法未通过单元测试,因为当copyCount
为0时,它严重失败。
我搜索了the documentation,看起来Groovy实现的范围就像是“连续值列表”。据我所知,范围并不代表整数区间的表示,因为它也有嵌入顺序的概念。
在Groovy中a..b
不是整数x的集合,而是a <= x <= b
。
在Groovy a..b
中,枚举u: [0,|b-a|] -> [a..b]
的定义为:u(0) = a
,适用于i
中的所有[1,|b-a|]
,u(i) = u(i-1) + sgn(b-a)
< / p>
现在我可以修复我的代码:
if (copyCount > 0) for ( i in 1..copyCount ) {
// Print files
}
同样在Groovy a..<b
中,枚举u: [0,|b-a|-1] -> [a..b-1]
的定义为:u(0) = a
,适用于i
中的所有[1,|b-a|-1]
,u(i) = u(i-1) + sgn(b-a)
我注意到下面的代码也适用于copyCount
正数或零:
for ( i in 0..<copyCount ) {
// Print files
}
尽管如此,如果我可以选择一种解决方案,在出现不一致的情况下将损害降至最低(例如copyCount
为-200,我可能会得到200张照片)......
0.step(copyCount, 1) {
// Print files
}
至少在这个解决方案中,如果出现负GroovyRuntimeException: Infinite loop
,我会得到copyCount
。它很时髦,但不是很漂亮,我觉得我在玩火。
还有这个解决方案,但我发现它很难看。
for ( i in 0..<[0,n].max() ) {
// Print files
}
因此,在这种情况下,我认为最好是避免使用范围运算符,因为对于习惯于Perl,Ruby或者数学或者法语的开发人员来说可能会让人感到困惑(对于这个范围的定义没有任何意义)在法语中,我们只会说“范围”为一个范围)...我也发现它在不一致的情况下更安全。不过,它并不那么时髦。
for ( i = 1 ; i <= copyCount ; i++ ) {
// Print files
}
为什么Groovy中的范围运算符如此复杂?正如我所看到的那样,这个步骤是“神奇地”确定并且我们不能强制它(如在Ruby中)这一事实是这个实现中的一个重大缺陷。我是唯一一个曾经为此感到困扰的人(两个印刷品而不是没有印刷品,这本来就是一个坏虫^^)?我错过了什么?是否有任何实际情况,当上限低于下限时,范围需要恢复顺序?我太挑剔了吗?