LISP功能影响其他功能

时间:2016-10-31 01:25:24

标签: lisp common-lisp literals

我注意到当我调用函数fillBoard时,它似乎工作,因为它填充了我想要传递给它的列表,但它有一个非常奇怪的副作用。不管怎样,一旦调用了fillBoard,clearBoard函数将只返回fillBoard返回的列表。另外,如果我再次调用fillBoard,它将继续更新clearBoard中返回的值。

据我了解,每次调用时都应该有一个清单的新实例清楚,所以我看不到它是如何被修改的,或者它是如何存储一个新值的。

我正在向fillBoard传递一个空列表,如((0 0 0 0)(0 0 0 0)(0 0 0 0)(0 0 0 0)),它将返回一个像((1 2 3)的列表0)(0 6 0 0)(0 0 0 0)(0 0 0 0)),然后是clearBoard返回的内容。

(defun fillBoard (list)

   (let ((numVals (+ 4 (random 3)))
         (rand 0)
     (val1 0)
     (val2 0))

     (dotimes (x numVals)

     (setf val1 (random 3))
     (setf val2 (random 3))
     (setf rand (nth val1 (nth val2 soln)))

     (prin1 rand)
     (write-line " ")


     (if (= (nth val1 (nth val2 list)) 0)
     (setf (nth val1 (nth val2 list)) rand)))
      list))



(defun clearboard ()
   (let (( list '((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0))))
    list))
编辑:我似乎通过将clearBoard传递给列表然后将其直接设置为空白板而不是局部变量,然后将其返回来解决问题。但是,我仍然对原始问题中发生的事情感到好奇

2 个答案:

答案 0 :(得分:3)

clearboard返回的列表定义为常量结构。在fillBoard中修改它时,您不是修改副本,而是修改结构本身。用

代替生成电路板
(loop repeat 4 collect (make-list 4 :initial-element 0))

答案 1 :(得分:3)

您的归档结果的EQness

您的函数始终返回相同的文字列表。它是嵌入到代码中的数据。不要修改它。

CL-USER 4 > (eq (clearboard) (clearboard))
T

EQ返回T,因为两个列表中的第一个缺点实际上是相同的缺点。

分配新的新列表

使用COPY-TREE内的clearboard创建新分配的列表列表,而不是一遍又一遍地返回相同的文字列表:

(defun clearboard ()
  (copy-tree '((0 0 0 0)
               (0 0 0 0)
               (0 0 0 0)
               (0 0 0 0))))


CL-USER 5 > (eq (clearboard) (clearboard))
NIL

不要修改文字数据

此处的文字数据是一个数据列表,嵌入在您的代码中。不要修改你的代码。