読者です 読者をやめる 読者になる 読者になる

No Programming, No Life

新しいNPNLです。http://d.hatena.ne.jp/fumokmm/ から引っ越してきました。

Groovyの動的型変換ではまった

GroovyはGroovy++などを使わない場合は静的型チェックしてくれず、よしなに動的型変換をしてくれる。(ということを忘れていてはまったのでメモしておこうと思います。)

動作確認: Groovy Version: 1.7.6 JVM: 1.6.0_22

型宣言されてる場合は動的にその型になる

def map = [a:1, b:2, c:3]
def defMap = map
assert java.util.LinkedHashMap == defMap.getClass()

String strMap = map
assert java.util.LinkedHashMap != strMap.getClass()
assert '{a=1, b=2, c=3}' == strMap

ということで、受けとる側で型を間違えてるといつのまにか型が変換されちゃっててはまります。

Stringに変換する時は#toString()が呼ばれてるみたい

class Hoge {
  String name
  @Override String toString() {
    "Hello! my name is $name."
  }
}
String strHoge = new Hoge(name: 'fumo')
assert 'Hello! my name is fumo.' == strHoge

まぁ考えてみれば当たり前か。

番外編: メソッド戻り値をvoidにしておくと結果が捨てられる

int getInt1(int n) { n }
assert java.lang.Integer == getInt1(10).class
assert 10 == getInt1(10)

def getInt2(int n) { n }
assert java.lang.Integer == getInt2(10).class
assert 10 == getInt2(10)

void getInt3(int n) { n }
assert null == getInt3(10)?.class

groovyではreturnを省略した場合、最後に評価した値が返却されるわけですが、その場合、戻り値をvoidとかに指定してると無視されてnullになっちゃうわけですね(#getInt3()参照)
ちなみに

void getInt4(int n) { return n }

とやると


org.codehaus.groovy.syntax.RuntimeParserException: Cannot use return statement with an expression on a method that returns void.

が発生するので安心ですね!*1

*1:ってことはreturnはやっぱり付けといたいいってことなのかな…?