我是lisp的菜鸟,只用了两个星期左右......
我有一些用setq声明的全局变量:
(setq myvar '(WHATEVER))
和一个应该修改我告诉它的变量的函数:
(defun MYFUN (varname)
(setq varname '(POOP))
)
但是当我拨打电话时:(MYFUN 'myvar)
并检查myvar
的值,现在它仍然是(WHATEVER)
如何在MYFUN
中进行更改?
答案 0 :(得分:5)
没有“使用setq声明全局变量”,只有“使用setq设置变量的值”,如果你在顶级词汇环境中这样做,结果是有趣的 - 定义
如果您查看变量varname
包含的内容,则可能是列表(poop)
。
此外,setq
末尾的“q”实际上意味着“引用”(即setq
特殊形式不会评估第一个(以及第三个和第五个......)参数,但将在第二个(以及第四个和第六个......)中这样做。
从历史上看,这是一种方便,(set (quote var) value)
不如(setq var value)
方便。但是,(set var value)
与(setf (symbol-value var) value)
具有完全相同的效果,您应该使用它。
答案 1 :(得分:4)
您正在设置局部变量varname
的值,而不是其包含名称的全局变量。要做你想做的事,你需要使用symbol-value
访问器间接通过它来获取全局值的变量。
(defun myfun (varname)
(setf (symbol-value varname) '(poop)))
答案 2 :(得分:1)
编辑:首先没有注意到这一点:
您在函数体的范围内都有本地varname
和全局varname
。本地名称会影响全局名称。因此,如果您将本地名称更改为var
,它应该按您编写的方式工作(在SBCL 1.2.13中检查)。但请考虑以下风格修正:
*
,因此它应为*myvar*
。全局变量特殊(有一种方法可以使它们正常,但它不一定是个好主意)。特殊变量具有动态范围,与正常变量的词法范围形成对比。defvar
或defparameter
声明变量。您可以使用setq
,但编译器会抱怨该变量未定义。此外,使用setq
变量也不会特殊。*myvar*
在函数体内显得特殊,则需要在函数定义之前声明它(使用defvar
或defparameter
),或者它需要是使用(declare (special *myvar*))
在函数正文中声明为特殊,然后使用defvar
或defparameter
声明。以下是声明和相应输出的可能组合的代码:
;; This is a model solution:
(defvar *myvar* 'a)
*MYVAR*
(defun foo (var)
(setq *myvar* var))
(foo 'b)
*myvar*
B
;; Not using DEFVAR or DEFPARAMETER
(setq myvar 'a)
A
(defun bar (var)
(setq myvar var))
;; The value of the global MYVAR is still changed
(bar 'b)
myvar
B
(defun show-myvar ()
myvar)
;; But MYVAR is not special
(let ((myvar 'z))
(show-myvar))
B
;; Also can assign value to undeclared variable
(defun bar2 (var)
(setq myvar-1 var))
BAR2
(setq myvar-1 'a)
A
;; And it works
(bar2 'b)
myvar-1
B
;; Finally: show special undeclared (yet) variable
(defun show-special ()
(declare (special *special-var*))
*special-var*)
(defvar *special-var* 'a)
*SPECIAL-VAR*
(let ((*special-var* 'z))
(show-special))
Z
;; The same but with SETQ: variable is still not special
(defun show-special-setq ()
(declare (special *special-var-setq*))
*special-var-setq*)
(setq *special-var-setq* 'a)
A
(let ((*special-var-setq* 'z))
(show-special-setq))
A