Javaのクロージャをいじってみた。(7)

unrestructured closureなるものが出てきた。キーワード==>とか。
このunrestructured closureの書きっぷり、Rubyのブロックっぽいな。

unrestructured closureを見てまずひらめくのは、多次元配列や
コレクションのforeachメソッドかな。多次元でもひとつのforeach()で
すべての要素をイテレーションする。
↓こんな感じの。

//定義側
package xxxx;
public class Matrix3 {
  public int[][] elements;

  public static void foreach(Matrix3 mat,
               {int==>int} closure) {
    int[] row = null;
    int element = 0;

    for (int i=0; i<elements.length; i++) {
      for (int j=0; j<elements[i].length; j++) {
        elements[i][j] = closure.invoke(elements[i][j]);
      }
    }
  }

  public Matrix3() {
    elements = new int[3][3];
    for (int i=0; i<elements.length; i++) {
      for (int j=0; j<elements[i].length; j++) {
        elements[i][j] = 0;
      }
    }
  }
}


//利用側
import xxxx.Matrix3;
import static xxxx.Matrix3.foreach;
  ;
void func() {
  Matrix3 mat = new Matrix3();
  foreach(int element : mat) {
    element = 10;
  }
}

というような感じ。

呼び出し側の記述は、":"の右側がforeach()の引数、左側は
クロージャ==>の仮引数を明示する。

またC#に習ってusingブロックみたいなメソッド作りたいなあ。
やりたいことはwithLockと同じで初期処理と終了処理で
クロージャ処理をはさむだけ。template patternぽいな。
例:

// Block.java
//定義側
package xxxx;
public class Block {
  static void using(Process ps, {Process==>void} closure) {
    ps.init();
    try {
      closure.invoke(ps);
    } finally {
      ps.dispose();
    }
  }
}

// Process.java
package xxxx;
public interface Process {
  public void init();
  public void dispose();
}


//利用側
import xxxx.Block;
import static xxxx.Block.using;
  ;
void func() {
  using(Process ps : new ProcessImpl()) {
     ((ProcessImpl)ps).execute();
  }
}

C#風のusingブロック完成!

例外処理は以下のように書けばできるみたいだけど、
これじゃあ汎用的な例外しか投げられない。
(そのため"throws E"とかいう例外ジェネリクスの導入の話があるらしい)

  static void using(Process ps,
          {Process==>void throws XXException})
    throw XXException
  {
    ...
  }

なんだか言語仕様がシンプルだったはずのjavaがどんどん複雑なものに。
そんなに差し迫って必要な文法じゃないと思うので、私はいらないと思う。
 
 

コメント

このブログの人気の投稿

日食ツアーその後

NashornがOpenJDKのリポジトリに入ってたのでビルドしてみた

Javaのクロージャをいじってみた。(1)