2017-03-25 21 views
2

私はSchemeを学んでいて、ちょうど閉鎖に出くわしました。上記のコードが評価されるとき、val10に等しいであろう、私が理解からScheme/RacketのClosureの目的は何ですか?

(define (create-closure x) 
    (lambda() x)) 

(define val (create-closure 10)) 

次の例では、クロージャの使用を示す、提供します。私はこれが単なる例であることを理解していますが、閉鎖がどのように役立つかはわかりません。そのようなコンセプトが必要とされるシナリオとは何でしょうか?私はあなたが与える例を信じ

答えて

1
  1. 、valが10に等しい、代わりに、ラムダオブジェクト(lambda() 10)ヴァルに割り当てられますれません。したがって、(val)は10に等しい。

  2. Schemeの世界では、同じ用語「クロージャー」を共有する2つの異なる概念があります。両方の用語の簡単な説明については、this postを参照してください。あなたの場合、私は "閉鎖"によってあなたが "語彙閉鎖"を意味すると信じています。コード例では、パラメータxは返されたラムダに対してfree variableであり、返されたラムダによって参照されるため、xの値を格納するために字句解析のクロージャが保持されます。 this postは、(字句的に)何が閉鎖されているかについての良い説明をあなたに与えるでしょう。

0

Lifu Huangの答えに完全一致します。

さらに、クロージャの最も明白な使用、つまりコールバックを強調したいと思います。

たとえば、JavaScriptで、私はこの場合、

function setup(){ 
    var presses = 0; 
    function handleKeyPress(evt){ 
    presses = presses + 1; 
    return mainHandler(evt); 
    } 
    installKeyHandler(handleKeyPress); 
} 

を書くかもしれませんが、それは私がキーハンドラとしてインストールしてる機能はpresses変数の結合「について知っている」という私にとって重要です。そのバインディングはクロージャーに格納されます。別の言い方をすると、関数はpressesのバインドで「閉じられます」。

JSで行われたほぼすべてのhttp GETまたはPOST呼び出しでも同様のことが起こります。それは他の多くの場所でも収穫されます。

1

valは、10ではありません。 (val)のように呼び出すと、xの値が返されます。 xはまだ使用されているので、依然として存在するクロージャ変数です。より良い例がこれです:

(define (larger-than-predicate n) 
    (lambda (v) (> v n))) 

(filter (larger-than-predicate 5) '(1 2 3 4 5 6 7 8 9 10)) 
; ==> (6 7 8 9 10) 

だから、述語はまだ5を保持する変数であるvと引数を比較します。動的バインドリスプでは、比較が行われるときにnが存在しないため、これを行うことはできません。

LecicalスコープはAlgolとSchemeに導入されました。 JavaScript、PHP amd C#はすべてalgolの方言であり、そこから継承しています。 Schemeはそれを得るための最初のリスプであり、Common Lispが続いた。実際には最も一般的なスコープです。

関連する問題