oop - 对这个 "oop under-the-hood"计数器示例如何工作感到非常困惑

标签 oop functional-programming scheme lisp racket

这是 make-counter 过程和对它的调用

(define make-counter
    (let ((glob 0))
        (lambda ()
            (let ((loc 0))
                (lambda ()
                    (set! loc (+ loc 1))
                    (set! glob (+ glob 1))
                    (list loc glob))))))

> (define counter1 (make-counter))
 counter1

> (define counter2 (make-counter))
 counter2

> (counter1)
(1 1)

> (counter1)
(2 2)

> (counter2)
(1 3)

> (counter1)
(3 4)

我不明白为什么 glob 表现为类变量,而 loc 表现为实例变量。

最佳答案

代码的每个部分何时运行可能是最容易考虑的。你评价

(define make-counter (let ((0 glob)) ...))

只有一次,所以 let 只被评估一次。这意味着只有一个 绑定(bind),并且它的值由let 主体内的所有内容共享。现在,let 的主体是什么?这是一个 lambda 函数,它成为 ma​​ke-counter 的值:

(lambda ()          ; this function is the value of make-counter

  (let ((loc 0))    ; so this stuff gets execute *each time* that
    (lambda ()      ; make-counter is called
      ...           ;
      )))           ;

现在,每次您调用 ma​​ke-counter 时,您都会评估(let ((loc 0)) (lambda () …)),它创建一个新绑定(bind)并返回一个可以访问它(以及从外部访问全局绑定(bind))的 lambda 函数。

因此调用 ma​​ke-counter 的每个结果都可以访问 glob单个绑定(bind),以及访问一个 per- loc 的结果绑定(bind)。

关于oop - 对这个 "oop under-the-hood"计数器示例如何工作感到非常困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31733160/

相关文章:

floating-point - 方案中的浮点精度和去除舍入误差

scheme - 如何从 Racket 中的 html 中提取元素?

oop - Golang OOP 架构,将 slice 传递给构造函数,创建 slice 对象

java - Java 中的类变量与传递参数 - 设计问题

functional-programming - N-Queens 示例程序奇怪的输出

javascript - 如果键的值未定义,如何不以对象文字表示法设置键

linux - *nix 有平衡方案 REPL 吗?

PHP 推荐从类实例发起数据库连接的方法

c++ - 初始化基类的引用成员

java - 使用Java和Vavr使用功能样式异常处理的逻辑