我在Racket / DrScheme中测试了以下代码:
(define (makem)
(define x 34)
(list (lambda () (set! x (+ x 1)) x)
(lambda () (set! x (+ x 1)) x))
)
(define f (car (makem)))
(define f2 (car (cdr (makem))))
> (f)
35
> (f2)
35 ; I thought this would give me 36
> (f)
36
> (f)
37
>
在函数调用中创建的每个lambda都会获取其范围内每个变量的副本吗?它是否像某种隐含的让?我期望lambdas有一些指向它们创建范围的指针,使它们能够访问堆栈变量,但这告诉我,因为f和f2似乎有不同的x副本。究竟发生了什么?
答案 0 :(得分:6)
您曾两次致电(makem)
,因此您使用两个不同的x
副本创建了两个不同的环境。如果您拨打(makem)
一次,就像这样:
(define m (makem))
(define f (car m))
(define f2 (car (cdr m)))
然后f
和f2
确实会共享x
m
中的{{1}}。