C#とJavaのクロージャ?
クロージャとは、、Wikipediaによると「引数以外の変数を実行時の環境ではなく、自身が定義された環境(静的スコープ)において解決する関数のことである。」そうである。
クロージャ - Wikipedia
C#でもクロージャっぽいことができるらしい。C#の場合デリゲートというみたい。
デリゲート - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
ほうほう。匿名メソッドを使ったら更にそれっぽいね。でも、クロージャというには「引数以外の変数を実行時の環境ではなく、自身が定義された環境(静的スコープ)において解決する」ってとこが大事なわけ。
C#はこの辺どうなんだろ。
うちにはLinuxしかないから試すの面倒なので、明日確認してこよう・・。
ちなみにJavaの場合は、定義元の変数にはfinalをつけないと、クロージャの中のコードからその変数は参照できなかったりする。(この前の日記で書いたmember_if関数をJavaで実装)
public interface Condition { boolean execute(int n); } public class Test { public static void main(String[] args) { int[] x = {-10,-5,-4,-3,0,10,20,30,40,50}; // 渡したい変数を定義 final int value = 0; int[] y = memberIf(x, new Condition() { public boolean execute(int n) { // valueのスコープはこのメソッドの外にあるが、finalをつけると // この関数のスコープからも参照出来る return n > value; } }); for (int i: y) { System.out.print(i + ","); } } private static int[] memberIf(int[] x, Condition c) { if (c == null) return null; for(int i = 0; i < x.length; i++) { if (c.execute(x[i])) { int[] members = new int[x.length - i]; System.arraycopy(x, i, members, 0, members.length); return members; } } return null; } }
実行結果はこんな感じ。
$ java Test 10,20,30,40,50,
ここで、finalを消してコンパイルしたら下のようなエラーとなる。
Test.java:9: ローカル変数 value は内部クラスからアクセスされます。final で宣言される必要があります。 return n > value; ^ エラー 1 個
ま、fainalつけたらアクセスできるね。これはクロージャというのかね??