Groovy の「?.」演算子*1について、ちょっと気になったことがあったのでメモ。
まず、以下のようなクラスがあるとしましょう:
class Foo{ def getNull(){ return null } }
getNull() メソッドは常に null を返します。 このメソッドの戻り値に対して「?.」演算子を使って処理を連結します。
++i
まず、「?.」演算子の後に呼び出されるメソッドの引数に「++i」を含める場合。 これは「妙な振る舞いだ」と思う人も、「普通だ」と思う人もいるかと思います。
def foo = new Foo() int i = 0 foo.getNull()?.someMethod(++i) assert i == 1
someMethod() メソッドは何処にも定義していないので呼ばれてないはずですが、++i は評価されて、最終的に変数 i の値は1になります。
i++
次は上記のコードで「i++」にした場合。
def foo = new Foo() int i = 0 foo.getNull()?.someMethod(i++) assert i == 1
結果は同じで、変数 i の値は1になります。
その他のメソッド
Java では「++i」や「i++」の評価の順序は「そう決まっている」と思うしかないんでしょうけど、Groovy では、これらはメソッド呼び出しになるので、上記と同じようなことがメソッド呼び出しでも起こるかもしれません。 ということで実際にやってみます。
まず、以下のようなクラスを作りましょう:
class Bar{ def println(){ println 'Bar' } }
Foo クラスは上のサンプルと同じとします。 このとき、
def foo = new Foo() def bar = new Bar() foo.getNull()?.someMethod(bar.println())
とすると、Bar#println() メソッドが実行されて「Bar」という文字列が表示されます。
結局、「?.」演算子の後にあっても、メソッドに渡される引数(の位置にある式)は評価されてしまうようです。 一見ややこしいコードはできるだけ書かないようにするべきなんでしょうけど、最後のメソッド呼び出しの例は、知らず知らずのうちにやってしまいそう。
- 作者: Dierk Konig,Andrew Glover,Paul King,Guillaume Laforge,Jon Skeet,杉浦孝,櫻井正樹,須江信洋,関谷和愛,佐野徹郎,寺沢尚史
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2008/09/27
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 146回
- この商品を含むブログ (121件) を見る