一个scheme closure小例子 - fun - fun
一个scheme closure小例子
写了两个小函数,不理解为什么有这样的结果,
1> (define self-add (let ((x 0)) (lambda () (set! x (+ x 1)) x))) (self-add) => 1 (self-add) => 2 (self-add) => 3 (self-add) => 4 2. (define self-add1 (lambda () (let ((x 0)) (set! x (+ x 1)) x))) (self-add1) => 1 (self-add1) => 1 (self-add1) => 1
在stackoverflow 问后,得到的结果如下:
The first function defines a local variable x
with an initial value of 0
and afterwards binds a lambda procedure to the name self-add
- so x
is "enclosed" by the lambda (that's why we say that the lambda behaves as a closure) and will be the same for all invocations of self-add
(you could say that x
is "remembered" by self-add
), and each time it gets called the value of x
will be incremented by one.
The second function binds the lambda to the procedure and afterwards defines a local variable x
inside the lambda - here x
is redefined each time self-add1
gets called, and will be different for all invocations: so x
is never "remembered" by self-add1
and is created anew every time the procedure gets called, initialized with 0
and then incremented, always returning the value 1
类似于局部变量和全局变量的区别。 需要加以注意的是,上面的程序是在运行着的解释器下执行的程序,执行一个函数时,对于lambda闭包需要记住的变量x,解释器会记录下来,因此下一次执行这个lambda函数时,绑定到lambda函数的变量,会以这个变量(这里为x)当前值为基础进行运算。