我使用范围运算符在 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 时严重失败。
我搜索了文档,似乎 Groovy 实现了“序列值列表”之类的范围。据我了解,范围并不代表整数区间的表示,因为它还具有嵌入顺序的概念。
在 Groovya..b
中不是整数 x 的集合,使得a <= x <= b
.
在 Groovya..b
中,枚举的表示u: [0,|b-a|] -> [a..b]
定义为:u(0) = a
, for all i
in [1,|b-a|]
,u(i) = u(i-1) + sgn(b-a)
现在我可以修复我的代码:
if (copyCount > 0) for ( i in 1..copyCount ) {
// Print files
}
同样在 Groovya..<b
中,枚举的表示u: [0,|b-a|-1] -> [a..b-1]
定义为:u(0) = a
, for all i
in [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 或数学或法语的开发人员感到困惑(法语中没有这个范围的定义,我们只会说一个范围的“intervalle”)......我还发现它在不一致的情况下更安全。不过,它并不是那么时髦。
for ( i = 1 ; i <= copyCount ; i++ ) {
// Print files
}
为什么 Groovy 中的范围运算符如此复杂?正如我所看到的,该步骤是“神奇地”确定的并且我们不能强制它(如在 Ruby 中)这一事实是此实现中的一个大缺陷。我是唯一一个对此感到困扰的人吗(两次打印而不是没有,这将是一个糟糕的错误^^)?我错过了什么?当上限低于下限时,是否有任何实际情况需要范围恢复顺序?是我太挑剔了吗?