我一直在研究常见的lisp教程,我刚刚被介绍到incf
和dolist
,我想看看我是否通过制作函数正确理解了dolist函数的功能inc-list
会将列表中的每个元素递增一个:
(defvar a-list (list 1 2 3))
(inc-list a-list) => (2 3 4)
以下是我定义的inc-list
的方法(defun inc-list (list)
(progn
(dolist (element list)
(incf element))
list))
这似乎不起作用。当我尝试(inc-list a-list)
时,我会回来(1 2 3)
和
a-list => (1 2 3)
。如果不是因为这样做,那就不会打扰我了。
(incf (car a-list))
(incf (cadr a-list))
(incf (caddr a-list))
给了我a-list => (2 3 4)
。 element
意味着什么秘密?
答案 0 :(得分:4)
element
依次绑定到列表的每个元素,即每个对的car
的值在某种意义上“复制”到它。然后,在incf
上调用element
,递增该变量的值,但不是从获取的列表位置。这就像你在做什么
(defvar element (car a-list))
(incf element)
(setq element (cadr a-list))
(incf element)
(setq element (caddr a-list))
(incf element)
此处,element
也会增加,然后每次都会立即“忘记”,因为setq
为新值。相比之下,(incf (car a-list))
会增加car
就地<{em>}的a-list
。如果您想要循环播放该行为,请忘记列表中的dolist
和loop on
:
(loop for position on lst
do (incf (car position)))
答案 1 :(得分:2)
(defvar a-list (list 1 2 3))
旁注:不要写这样的全局变量。写*a-list*
。否则,全局动态变量会影响您的局部变量。
(defun inc-list (list)
(progn
(dolist (element list)
(incf element))
list))
您不需要PROGN
。 DEFUN
已经允许一系列表单,DOLIST
也是如此。
(defun inc-list (list)
(dolist (element list)
(incf element))
list)
以上就足够了。
DOLIST
是一个引入名为ELEMENT
的新(!)局部变量的表单。
DOLIST
在每次迭代中设置ELEMENT
的值。
您所做的只是在每个迭代步骤中递增ELEMENT
的值。
你的副作用会丢失。原始LIST没有改变。否则不使用ELEMENT
的值。