考虑到动态和词法绑定(bind)变量的行为,我理解以下代码中 symbol-value
的输出(动态绑定(bind)变量 a
被词法绑定(bind)所遮蔽)变量a
(该解释是错误的,请参阅下面的编辑)):
(defvar a 1)
(let ((a 2))
(list a (symbol-value 'a)))
; => (2 2)
但是当使用progv
创建类似的环境时,symbol-value
给出了不同的结果:
(progv '(x) '(1)
(let ((x 2))
(list x (symbol-value 'x))))
; => (2 1)
为什么在第二个示例中 (symbol-value 'x)
返回 1
?
最终编辑伴随着接受的答案:在 Rainer Joswig 的回答中的整个评论中,我了解到 (let ((a 2)) ... )
不绑定(bind)词法变量,但隐藏了前一个动态绑定(bind)的值。 Martin Buchmann 在评论中还指出,symbol-value
忽略了词汇变量。
最佳答案
PROGV
特殊形式创建动态绑定(bind),但不会将变量声明为封闭形式的特殊。
因此我们需要将变量 x
的 LET
绑定(bind)声明为特殊的:
CL-USER 27 > (progv '(x) '(1)
(let ((x 2))
(declare (special x))
(list x (symbol-value 'x))))
(2 2)
DEFVAR
OTOH 声明其变量是特殊的。在全局范围内,没有直接的方法可以撤消该声明。
关于common-lisp - `symbol-value` 中 `progv` 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66944937/