カプセル化とクロージャーについて、私が本当に理解していないことがあります。カプセル化は、コードで変更しないと変更できないものだと思います。しかし、クロージャーとカプセル化がコードにどのように適用されるかを説明するように求められたとき、私は本当に理解できません。
例えば :
(define new-cercle #f)
(let ((n 0))
(set! new-cercle
(lambda (rayon)
(begin
(set! n (+ n 1))
(lambda (msg)
(cond ((eq? msg ’circonference)
(* 2 3.14 rayon))
((eq? msg ’surface)
(* 3.14 rayon rayon))
((eq? msg ’nb-cercles)
n)))))))
n
、右カプセル化されていますか?したがって、問題は、カプセル化とクロージャがこのコードにどのように適用されるかを説明することです。
私が理解していないもう一つのことは、なぜlet
ここでラムダの上になければならないのですか?下に置くとlambda
、関数がうまく機能せず、アキュムレータがないのはなぜですか?
(define acc
(let ((n 1))
(lambda (x)
(set! n (* n x))
n)))
私がグーグルで検索したとき、正直なところ、ほとんどのトピックにある複雑な例では何も理解できなかったので、誰かがこれを簡単な方法で説明してくれることを願っています。
些細なケースでは、いくつかの違いがなくなるため、おそらく問題が発生しています。たとえば、両方(let ((n 1)) (lambda (x) n))
と(lambda (x) (let ((n 1)) n)
基本的に同じ機能を提供します。
あなたの例では
(define acc (let ((n 1))
(lambda (x) (set! n (* n x)) n)))
順序let
とはlambda
重要です。それらを交換すると(lambda (x) (let ((n 1)) ...
、呼び出すたびにこの関数n
は再びにバインドされ1
ます。代わりにn
、値で始まり1
、関数によって変更でき、関数が完了しても消えない場所があるようにします(let ((n 1)) (lambda (x) (set! n ...
。これは、を持っているときに得られるものです。
インナーによって構築された機能lambda
は、アウターの使用をキャプチャし、n
それ自体が存続する限り、その場所を保持します。またn
、この関数以外は参照できないため、カプセル化されます。また、関数はの周囲のバインディングによって閉じられn
、関数は(のn
)クロージャであるとも言います。
字句スコープについて読むことも役立つかもしれません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加