1

我使用范围运算符在 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 iin [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 iin [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 中)这一事实是此实现中的一个大缺陷。我是唯一一个对此感到困扰的人吗(两次打印而不是没有,这将是一个糟糕的错误^^)?我错过了什么?当上限低于下限时,是否有任何实际情况需要范围恢复顺序?是我太挑剔了吗?

4

0 回答 0