在有关参数化的球拍指南中,有以下代码:
(define location (make-parameter "here"))
(let ([get (parameterize ([location "with a fox"])
(lambda () (location)))])
(get))
代码返回"here"
。
评估这段代码的顺序是什么?谢谢你。
这是许多语言(不仅仅是 Racket)中动态范围值的常见问题。以下是评估代码时发生的情况:
location
值定义"here"
let
...parameterize
...location
随值动态更新"with a fox"
lambda
表达式以创建一个关闭的闭包location
parameterized
块返回——参数location
恢复到它的原始值"here"
lambda
必然get
let
身体...(get)
,它会查找 的当前值location
,即 ,这就是"here"
结果。如果您仔细阅读有关参数的文档,它会解释参数始终采用堆栈中最近更新的值。由于您对值的更新"with a fox"
在进入let
正文之前已从堆栈中弹出,因此当您实际调用get
. 一个简单的解决方法是从参数复制值并让闭包关闭副本:
(define location (make-parameter "here"))
(let ([get (parameterize ([location "with a fox"])
(let ([loc (location)])
(lambda () loc)))])
(get))
现在lambda
closes over loc
,它应该具有预期值。