同じコードを複数回実行するために、範囲演算子を使用して 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
。
Groovyでは、次のように定義されa..b
た列挙の表現です。u: [0,|b-a|] -> [a..b]
u(0) = a
i
[1,|b-a|]
u(i) = u(i-1) + sgn(b-a)
これで、コードを修正できます。
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、数学、またはフランス語に慣れている開発者にとっては混乱を招く可能性があるからです (この範囲の定義をフランス語で表す言葉はありません。範囲については「intervalle」と言うだけです)...また、矛盾がある場合でも安全であることがわかりました。それでも、それほどグルービーではありません。
for ( i = 1 ; i <= copyCount ; i++ ) {
// Print files
}
Groovy の範囲演算子はなぜ複雑なのですか? 私の理解では、ステップが「魔法のように」決定され、(Ruby のように) それを強制できないという事実は、この実装の大きな欠陥です。これに悩まされたことがあるのは私だけでしょうか? 私は何か見落としてますか?上限が下限よりも低くなったときに、範囲の順序を元に戻す必要がある実際のケースはありますか? 私はうるさいですか?