0

クロージャは、本体に変数​​ x と内部関数 F を持つ外部関数 O です。F は x にアクセスする必要があります。O は F を返す必要があります。つまり、F の戻り値ではなく、F 自体 (またはそのポインター) を返す必要があります。このように、F は O の外部のコードから呼び出すことができ、F は x を実行する必要があるため、x は後でスコープ内に保持する必要があります。おお出口。

JavaScript では、関数内で関数を定義できるので、簡単です。C# では、匿名メソッドまたは匿名デリゲートを使用して、内部関数と同じ動作をさせる必要があります。

クロージャーの本質は、関数が終了した後、関数のローカル変数の値を保持することです。これにより、次に関数が呼び出されたときに、以前の値が既に存在します。上記の構文と手法は、クロージャーを実現する方法です。

とにかく、内部関数やデリゲートを使用せずにクロージャの本質を持つ言語 (アセンブリ言語以外) はありますか。もちろん、OOP のクラスのフィールドも同じ効果がありますが、それ以外の方法を探しています。

4

2 に答える 2

1

クロージャは、定義上、レキシカル スコープ内の変数を閉じます。ローカル変数を使用して他の何かの「内側」にできない場合、まったく役に立ちません。したがって、ほとんどの場合、クロージャーは何らかの関数内に存在できる必要があります。

ただし、1 つの複雑さは、一部の言語のクロージャーが無名関数と密接に関連付けられていることです。(無名関数は一般にクロージャーでなければなりません。クロージャーは無名関数である必要はありませんが、一部の言語では、クロージャーは無名関数のみです。)また、無名関数の構文は、通常の (名前付き) 関数の構文とは異なる場合があります (特に、関数と変数の個別の名前空間 (名前付き関数は関数名前空間に含まれますが、無名関数はデータになります)。また、これらの言語の一部には、「内部」の名前付き関数がありません。

たとえば、PHP では、すべての名前付き関数はグローバル スコープにあります。名前付き関数の定義を別の関数内に (直観に反して) 配置すると、外側の関数が実行されるときに (外側のスコープで宣言されているが遅延されているかのように)、内側の関数がグローバル スコープで定義されます (外側のコードから参照できます)。ただし、PHP 5.3+ にはクロージャである無名関数もあります。人々は一般的に無名関数を「クロージャー」と呼んでいます。これは、言語で唯一のクロージャーであるためです。

もう 1 つの例は Ruby です。def構文はメソッドを定義します。メソッドを別のメソッド内で (直感に反して) 定義しても、そのメソッドは他のメソッドから見えるものとして定義されます。Ruby には、lambdaproc、またはProc.new構文のいずれかを使用するクロージャーである無名関数もありますが、それらは構文的に異なります。

于 2012-06-12T18:20:07.960 に答える
0

私はそれらをクロージャーとは呼びませんが、ローカル変数が状態を保持するという概念は、ローカル変数を使用する VB にありStaticます。

Sub Example()
  Dim normalVar As Integer
  Static staticVar As Integer

  normalVar += 1
  staticVar += 1

  Console.WriteLine("{0} {1}", normalVar, staticVar)
End Sub

(これは VB.NET ですStaticが、VB3 以前にありました。)

これは出力されます

1 1
1 2
1 3

3回呼び出された場合。

于 2012-11-14T14:48:14.120 に答える