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作为参数传递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 仅适用于一个帐户,而代码 2 在每次调用时“创建一个新帐户”——对过程的调用返回您需要绑定到变量的调度过程,并且然后如上图使用。

因此,您会得到本地状态丢失的印象;不是,您可能每次都在创建一个新帐户。

于 2014-11-02T08:24:45.080 回答