我正在使用动态变量,让我们调用其中一个*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*)
答案 0 :(得分:6)
定义
(defparameter *x* 10)
(defun change-value (varname) ; the argument name is misleading!
(setf varname 20))
并且调用(change-value *x*)
不会给你带来任何东西,因为change-value
是一个函数而你只是将10
作为参数传递给它;它不知道涉及*x*
。因此,该函数所做的是修改变量varname
的局部绑定,将其从10
更改为20
并返回后者。
您需要传递symbol
(变量名称)本身:
(defun change-value (varname)
(setf (symbol-value varname) 20))
并将其称为(change-value '*x*)
(请注意'
之前的引号*x*
。
答案 1 :(得分:2)
这似乎有效:
(defparameter *x* 'initial)
(defun change-dyn (variable value)
(setf (symbol-value variable) value))
(change-dyn '*x* 'final)