在关于parameterize的“球拍指南”中,有以下代码:
(define location (make-parameter "here"))
(let ([get (parameterize ([location "with a fox"])
(lambda () (location)))])
(get))
代码返回"here"
。
评估这段代码的顺序是什么?谢谢。
答案 0 :(得分:5)
这是许多语言(不仅仅是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
关闭了loc
,它应具有预期值。