【问题标题】:Local state of a variable变量的局部状态
【发布时间】:2014-12-29 02:05:36
【问题描述】:

我正在尝试完全理解对象及其变量的局部状态

这段代码似乎对多次调用的同一过程产生了不同的结果,这意味着局部变量发生了变化:

(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 的参数传递?

谢谢

【问题讨论】:

    标签: scheme racket let object-state


    【解决方案1】:

    测试代码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 在每次调用时“创建一个新帐户”——对过程的调用返回您需要绑定到变量的调度过程,并且然后使用如上图。

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

    【讨论】:

    • 哈,我明白了。当我测试程序时,我运行了(define acc make-account) (((acc) 'withdraw) 50),这样每次使用acc 时都会定义一个新的局部变量
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    相关资源
    最近更新 更多