Dart: Structured web apps [12] Functionとclosure

DartにはファーストクラスのFunctionがあります。

簡単な例をみてみましょう。クロージャの例をあげています。fはx+nを返す関数を作りだします。f(2)と呼ぶと、「(x)=>x+2」の関数を作ります。gは合成関数を作っています。f(Math.sin)と呼ぶと、「(x,y)=>Math.sin(x)*y」という関数を作ります。こういった処理を合成することが言語機能として簡単にできるようになっているところがうれしいですね。

Function f(num n) {
  return (x) => x + n;
}
Function g(Function _f) {
  return (num x, [num y=1]) => _f(x) * y;
}
main() {
  int n = 2;
  var f0 = f(n);
  print(f0(1)); // 3
  n = 3;
  var f1 = f(n);
  print(f0(1)); // 3
  print(f1(1)); // 4

  print("----------");
  var g0 = g(f0);
  for(num x=0; x<5; x+=1) {
    print(g0(x)); 
  }
  print("----------");
  var g1 = g(f1);
  for(num y=0; y<5; y+=1) {
    print(g1(2, y)); 
  }
}

例では、f(n)のように変数を渡していますが、この例ではf(2)のようにしても同じです。「f0=f(n);」としてからnの値を変更しても、f0には影響がありません。f0の中で使われている変数nは「f0=f(n);」とした時点でキャプチャされてf0という関数と結びついて用意されます。

実行結果は次のようになります。「g0(x)」はxに2を足した値になりますし、「g1(2, y)」はf1(2)*yつまり5*yの値になりますから、そのことを理解して結果を確認してください。

3
3
4
----------
2
3
4
5
6
----------
0
5
10
15
20

クロージャはコールバックの仕組みを提供したり利用したりするときに便利ですから、覚えておきたいテクニックです。

同じタグの記事: Dart
同じタグの記事: dartlang
同じカテゴリの記事: Program