2

我正在使用动态变量,让我们调用其中*x*一个值为 10。

我想通过将变量的名称作为参数传递来通过函数调用来更改其值:

(defun change-value (varname)
  (setf varname 20))

然后打电话(change-value *x*). 如果我理解正确,varname则采用本地范围,因此在setf外部没有影响change-value。因此,*x*之后仍为 10。

我的问题是,有没有办法让*x*通过类似于上面的函数调用使等于 20?我尝试添加(proclaim '(special varname))并且(declare (special varname))他们似乎没有做任何事情。

哦,定义一个宏或多或少地做了我想要的,但我怀疑这是一个好习惯:

(defmacro change-value-macro (varname)
  `(setf ,varname 20))

(change-value-macro *x*)
4

2 回答 2

6

定义

(defparameter *x* 10)
(defun change-value (varname) ; the argument name is misleading!
  (setf varname 20))

调用(change-value *x*)不会给你买任何东西,因为change-value它是一个函数,你只是将它10作为参数传递;它不知道这*x*涉及到什么。因此,该函数所做的是修改变量的本地绑定varname,将其从 更改1020并返回后者。

您需要传递symbol(变量名)本身:

(defun change-value (varname)
  (setf (symbol-value varname) 20))

并将其称为(注意前面(change-value '*x*)的引号)。'*x*

于 2013-06-26T19:17:37.557 回答
2

这似乎有效:

(defparameter *x* 'initial)

(defun change-dyn (variable value)
  (setf (symbol-value variable) value))

(change-dyn '*x* 'final)
于 2013-06-26T19:18:07.420 回答