今回は基本データ型、特に数値について『Groovyイン・アクション』Chapter3 を参考にしています(一覧)。
- Groovy の基本的アプローチ
- 数値リテラル
- 数値リテラルの宣言、型指定
- 演算子オーバーライド、演算子オーバーロード、演算子実装
- 強制型変換
- 数値に関するユーティリティ・メソッド
- 作者: Dierk Konig,Andrew Glover,Paul King,Guillaume Laforge,Jon Skeet,杉浦孝,櫻井正樹,須江信洋,関谷和愛,佐野徹郎,寺沢尚史
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2008/09/27
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 146回
- この商品を含むブログ (121件) を見る
Groovy の基本的アプローチ
数値リテラル
型 | リテラルの例 |
---|---|
java.lang.Integer | 15, 0x1234ffff |
java.lang.Long | 100L*1 |
java.lang.Float | 1.23f, 4.56F |
java.lang.Double | 1.23d, 4.56D |
java.math.BigInteger | 123g, 456G |
java.math.BigDecimal | 1.23, 4.5e6, 7.8E9, 1.23g, 4.56G |
- 整数リテラルのデフォルト型は Integer
- 非整数リテラルのデフォルト型は BigDecimal
- 「g, G」接頭辞が付いたリテラルは BigInteger または BigDecimal。 小数点の有無で判別。
数値リテラルの宣言、型指定
数値リテラルの宣言をあれこれ列挙。 Byte, Short は省略
//***** Integer ***** int i1 = 1 Integer i2 = 1 def i3 = 1 def i4 = (int)1 def i5 = (Integer)1 def i6 = 1 as int def i7 = 1 as Integer
//***** Long ***** long l1 = 1 Long l2 = 1 def l3 = 1L def l4 = (long)1 def l5 = (Long)1 def l6 = 1 as long def l7 = 1 as Long
//***** Float ***** float f1 = 1 Float f2 = 1 def f3 = 1f def f4 = 1F def f5 = (float)1 def f6 = (Float)1 def f7 = 1 as float def f8 = 1 as Float
//***** Double ***** double d1 = 1 Double d2 = 1 def d3 = 1d def d4 = 1D def d5 = (double)1 def d6 = (Double)1 def d7 = 1 as double def d8 = 1 as Double
//***** BigInteger ***** BigInteger bi1 = 1 def bi2 = 1g def bi3 = 1G def bi4 = (BigInteger)1 def bi5 = 1 as BigInteger
//***** BigDecimal ***** BigDecimal bd1 = 1 def bd2 = 1.0 def bd3 = 1.0g def bd4 = 1.0G def bd5 = (BigDecimal)1 def bd6 = 1 as BigDecimal
//***** Character ***** char c1 = 'a' Character c2 = 'a' char c3 = 0x61 Character c4 = 0x61 def c5 = (char)0x61 def c6 = (Character)0x61 def c7 = 'a' as char def c8 = 'a' as Character def c9 = 'a'.toCharacter()
演算子オーバーライド、演算子オーバーロード、演算子実装
特に言葉の細かな違いを気にする必要なし。 「演算子オーバーロード」が一般的なのかな?
- Groovy での演算子はすべてメソッド呼び出し
- 特定のインターフェースを実装する必要はない。 メソッド名と引数の個数が一致していれば良さそう。
こちらを優先して参照。
単項演算子
演算子 | メソッド | 対象 |
---|---|---|
+a | a.positive() | 整数 |
-a | a.negative() | 整数 |
~a | a.bitwiseNegate() | 整数、文字列 |
a++, ++a | a.next() | 数値、文字列、範囲 |
a--, --a | a.previous() | 数値、文字列、範囲 |
『Groovyイン・アクション』には positive(), negative(), bitwiseNegate() がなく、代わりに negate() が載ってますが、Groovy1.7 では動かなかったので省略。
2項演算子
演算子 | メソッド | 対象 |
---|---|---|
a + b | a.plus(b) | 数値、文字列、コレクション |
a - b | a.minus(b) | 数値、文字列、コレクション |
a * b | a.multiply(b) | 数値、文字列、コレクション |
a / b | a.div(b) | 数値、文字列 |
a % b | a.mod(b) | 数値、文字列 |
a**b | a.power(b) | 数値 |
a | b | a.or(b) | 整数 |
a & b | a.and(b) | 整数 |
a ^ b | a.xor(b) | 整数 |
a << b | a.leftShift(b) | 整数。 StringBuilder, Writer, File, Socket, リストなどへの「追加」 |
a >> b | a.rightShift(b) | 整数 |
a >>> b | a.rightShiftUnsigned(b) | 整数 |
a == b | a.equals(b) | オブジェクト |
a != b | ! a.equals(b) | オブジェクト |
a <=> b | a.compareTo(b) | java.lang.Comparable |
a < b | a.compareTo(b) < 0 | java.lang.Comparable |
a <= b | a.compareTo(b) <= 0 | java.lang.Comparable |
a > b | a.compareTo(b) > 0 | java.lang.Comparable |
a >= b | a.compareTo(b) >= 0 | java.lang.Comparable |
「==」演算子は equals() メソッドを呼び出すことに注意。 Java ではこれらは別物。
その他
演算子 | メソッド | 対象 |
---|---|---|
switch(a){ case b: } |
b.isCase(a) | オブジェクト、範囲、リスト、コレクション、パターン、クロージャ コレクション c に対する c.grep(b) |
a[b] | a.getAt(b) | オブジェクト、リスト、マップ、文字列、配列 |
a[b] = c | a.putAt(b, c) | オブジェクト、リスト、マップ、StringBuilder、配列 |
a as type | a.asType(typeClass) | 任意の型 |
強制型変換
演算子「+, -, *」について、計算結果の型を表に(『Groovyイン・アクション』より)。 結果が Byte, Short, Character, Float になることはない模様:
+-* | Byte | Short | Integer | Character | Long | BigInteger | BigDecimal | Float | Double |
---|---|---|---|---|---|---|---|---|---|
Byte | I | I | I | I | L | BI | BD | D | D |
Short | I | I | I | I | L | BI | BD | D | D |
Integer | I | I | I | I | L | BI | BD | D | D |
Character | I | I | I | I | L | BI | BD | D | D |
Long | L | L | L | L | L | BI | BD | D | D |
BigInteger | BI | BI | BI | BI | BI | BI | BD | D | D |
BigDecimal | BD | BD | BD | BD | BD | BD | BD | D | D |
Float | D | D | D | D | D | D | D | D | D |
Double | D | D | D | D | D | D | D | D | D |
他の演算子も含めていくつかサンプルを:
//***** 整数 ***** def x1 = 1f * 2f assert x1 == 2d assert x1 instanceof Double // Java では Float def x2 = ((byte)1) + ((byte)2) assert x2 == 3 assert x2 instanceof Integer // Java では Byte def x3 = Integer.MAX_VALUE + 1 assert x3 == Integer.MIN_VALUE assert x3 instanceof Integer def x4 = 1 / 2 assert x4 == 0.5 // Java では 0 assert x4 instanceof BigDecimal // Java では Integer def x5 = 1.intdiv(2) // Java での 1 / 2 と同じ assert x5 == 0 assert x5 instanceof Integer
注意が必要なのは「1 / 2 == 0.5」でしょうか。 Java での整数の割り算をしたい場合は intdiv() メソッドを使う必要があります。
//***** 冪乗演算子 ***** def p1 = 2**30 assert p1 == 1073741824 assert p1 instanceof Integer def p2 = 2**31 assert p2 == 2147483648L assert p2 instanceof Long def p3 = 2**3.5 assert p3 instanceof Double
『Groovyイン・アクション』に載っている例では、「2**31 が Integer」となってますが、これは間違い(Java でも)。 Integer は -231 〜 231-1 (-2**31 〜 2**31 - 1)
//***** BigXxxx ***** def g1 = 1G + 2G assert g1 == 3G assert g1 instanceof BigInteger def g2 = 1.0G + 2G assert g2 == 3.0 assert g2 instanceof BigDecimal
数値に関するユーティリティ・メソッド
数値に定義されているユーティリティ・メソッド:
- times()
- upto()
- downto()
- step()
//***** times() ***** def store1 = '' 5.times { store1 += 'x' } assert store1 == 'xxxxx'
//***** upto() ***** def store2 = '' 1.upto(5){ number -> store2 += number } assert store2 == '12345'
//***** downto() ***** def store3 = '' 5.downto(1){ number -> store3 += number } assert store3 == '54321'
//***** step() ***** def store4 = '' 0.step(0.3, 0.1){ number-> store4 += number + ' ' } assert store4 == '0 0.1 0.2 '
*1:100l も可能だが、1と間違えやすいので非推奨。