1

オブジェクトとその変数のローカル状態を完全に理解しようとしています

このコードは、複数回呼び出された同じプロシージャに対して異なる結果を生成するようです。つまり、ローカル変数が変更されます。

(define new-withdraw
  (let ((balance 100))
    (lambda (amount)
      (if (>= balance amount)
          (begin (set! balance (- balance amount))
                 balance)
          "Insufficient funds"))))

この他のコードでは、同じ結果が生成されます。つまり、すべてのプロシージャ コールに対して新しいローカル変数が作成されます。

(define (make-account)
  (let ((balance 100))
    (define (withdraw amount)
      (if (>= balance amount)
          (begin (set! balance (- balance amount))
                 balance)
          "Insufficient funds"))
    (define (deposit amount)
      (set! balance (+ balance amount))
      balance)
    (define (dispatch m)
      (cond ((eq? m 'withdraw) withdraw)
            ((eq? m 'deposit) deposit)
            (else (error "Unknown request -- MAKE-ACCOUNT"
                         m))))
    dispatch))

私の質問は次のとおりです。

  • letを使用してローカル変数を作成しているにもかかわらず、動作が異なるのはなぜですか?

  • balanceのパラメーターとして渡さずに、2 番目のコードを最初のコードとして機能させる方法はありますmake-accountか?

ありがとうございました

4

1 に答える 1

2

テスト コード 1:

> (new-withdraw 0)
100
> (new-withdraw 50)
50
> (new-withdraw 10)
40

テスト コード 2:

> (define ac (make-account))
> ((ac 'withdraw) 0)
100
> ((ac 'withdraw) 50)
50
> ((ac 'withdraw) 10)
40

したがって、両方のコードがローカルの状態を維持します。コード 1 とコード 2 の違いは、コード 1 は 1 つのアカウントに対してのみ機能するのに対し、コード 2 は呼び出しごとに「新しいアカウントを作成する」ことです。プロシージャへの呼び出しは、変数にバインドする必要があるディスパッチ プロシージャを返します。次に、上記のように使用します。

したがって、ローカルの状態が失われているような印象を受けます。そうではありません。おそらく毎回新しいアカウントを作成していたでしょう。

于 2014-11-02T08:24:45.080 に答える