sha*_*ica 3 lisp scope sbcl common-lisp
我了解此代码的工作原理:
(defvar *nums* '(2 3 5))
(defun print-nums ()
(format t "~a~%" *nums*))
(print-nums)
-> (2 3 5)
-> NIL
Run Code Online (Sandbox Code Playgroud)
我什至明白动态绑定变量的新值是如何在这段代码中*nums*传递的print-nums:
(let ((*nums* '(1 2 3)))
(print-nums))
-> (1 2 3)
-> NIL
Run Code Online (Sandbox Code Playgroud)
但是为什么下面的代码不能以同样的方式工作?
(defvar *my-nums-f* (let ((*nums* '(1 2 3)))
#'(lambda () (format t "~a~%" *nums*))))
(funcall *my-nums-f*)
-> (2 3 5)
-> NIL
Run Code Online (Sandbox Code Playgroud)
闭包的概念是否不适用于动态绑定变量,还是我做错了什么?如果我错误地理解了闭包的概念,有人可以向我解释一下吗?
(defvar *my-nums-f* (let ((*nums* '(1 2 3)))
#'(lambda () (format t "~a~%" *nums*))))
Run Code Online (Sandbox Code Playgroud)
这里我们设置*my-nums-f*为
(let ((*nums* '(1 2 3)))
#'(lambda () (format t "~a~%" *nums*)))
Run Code Online (Sandbox Code Playgroud)
这种形式首先动态绑定*nums*到'(1 2 3),然后返回#'(lambda () (format t "~a~%" *nums*)),这是一个函数。最后,我们重置*nums*回'(2 3 5).
(funcall *my-nums-f*)
Run Code Online (Sandbox Code Playgroud)
这里我们调用存储在 中的函数*my-nums-f*,即(lambda () (format t "~a~%" *nums*))。此函数获取 的当前值*nums*,即'(2 3 5)。
-> (2 3 5)
-> NIL
Run Code Online (Sandbox Code Playgroud)
您似乎期望以lambda某种方式内联函数体中使用的所有变量的当前值,这确实会导致(format t "~a~%" '(1 2 3))该点。
但这不是它的工作原理:函数引用变量本身,而不是变量值的快照。这就是为什么该函数*nums*在调用它时会看到 的当前值。