Groovyの奇妙な演算子(その2)
お待ちかね?「Groovyの奇妙な演算子」第二回は、
<=> .. ..< ... * *:
の6つについてです(予告とはちょっと違います)。
「<=>」大小比較演算子
両辺に与えた2つの数値の大小比較を行い、その結果を返します。
a<=>bの結果は
- 1(a>b)
- 0(a==b)
- -1(a
のいずれかとなります。
明示的に呼び出して使うより、java.util.Comparable#compareTo()を実装するなどに使うのが主になると思われます。
「..<」半開区間をあらわす範囲オブジェクト(groovy.lang.IntRangeなど)を生成します。
「..<」は、「Javaにない演算子」ではありますが、意味はある程度自明で、つまりa,bが整数値のとき、「a ..< b」は、「new IntRange(a,b)」と等価です。
IntRangeはgroovyで定義された、整数の半開区間を表すクラスです。a ..< bは半開区間[a,b)を表します。
【用途】
IntRangeはItarableを実装しているので、拡張for文などでループ範囲の指定に使えます。
groovy> for (i in 1..<5) { groovy> println i groovy> } groovy> go 1 2 3 4
次に、IntRangeのeachメソッドを、クロージャを引数に渡して呼び出してみます。
こちらのほうがよりGroovyらしいですね。
groovy> (1..<5).each{ groovy> println it groovy> } groovy> go 1 2 3 4
「..<」は、上でわかるように、「終端を含まない」範囲を指定します。
【覚え方】
覚え方としては、●−−−○という数直線の表現を連想するとか。
あるいは、<は「より小さい」だから、末端を含まないもの、とか。
「..」は、「終端を含む」範囲を指定します。
【用途】
やはり以下のようにループの繰り返し回数指定に用いることができます。
groovy> for (i in 1..5) { groovy> println i groovy> } groovy> go 1 2 3 4 5
groovy> (1..5).each{ groovy> println it groovy> } groovy> go 1 2 3 4 5
「..」は「..<」と同様にIntRangeを返すのですが、IntRangeのコンストラクタは「終端を含まない」範囲を指定して呼び出す必要があるので、a..bと等価なコードは以下のようになります。
- new groovy.lang.IntRange(a, b.next()) (b>a)
- new groovy.lang.IntRange(a, b.previous())(b
- new groovy.lang.EmptyRange() (b==a)
ちょっとややこしいですかね。まあおそらくあんまり気にする必要はないでしょう。
「...」(Java5と同様に)可変個数引数をあらわす指定
の様である。しかし、使えるが微妙にJava5とは異なる意味となる(バグ?)。もともと、Groovyでは、配列を引数とすることで、可変個数引数を使えるので、「...」を使う必要がない、はず。ちなみに「演算子」ではありませんね。
「*」リスト展開演算子(SPREAD LIST OPERATOR)。
リストの初期化で使用可能。
[1, *[2, 3], 4] は [1, 2, 3, 4]と等価。
「*:」マップ展開演算子(SPREAD MAP OPERATOR)。
マップの初期化で使用可能。
m = ['a':11, 'aa':22, 'aaa':33] z = ['c':100, *:m]
は、
z = ['c':100, 'a':11, 'aa':22, 'aaa':33]
と等価。Beanの初期化時にも使えます。
リストもそうですが、明示的に展開しないと展開されないというわけです。
次回予告
以下についてのその3に続く(たぶん)。
=~ ==~ ** **= ===