在这个档案中,我得到9个“假定特殊”的警告。他们是
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special in SETQ
;;;*** Warning in CHECK-ROW: RESULT assumed special in SETQ
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special
;;;*** Warning in CHECK-ROW: RESULT assumed special in SETQ
;;;*** Warning in CHECK-ROW: RESULT assumed special
整个文件只有两个功能 -
(defun get-element (x y board)
(nth y (nth x board)))
(defun check-row (row board)
(setq checkarray (make-array 9))
(setq result T)
(fill checkarray 0)
(loop for i upto 8 do
(setf (aref checkarray (- (get-element row i board) 1))
(+ (aref checkarray (- (get-element row i board) 1)) 1))
)
(loop for i upto 8 do
(if (or (= (aref checkarray i) 0) (> (aref checkarray i) 1))
(setq result nil) ())
)
result)
我没有得到任何错误,功能似乎工作正常。那为什么这么说呢?我该如何解决?
答案 0 :(得分:8)
Rainer Joswig的回答一般是正确的。在您的情况下,我认为不需要将这些变量设置为全局变量,因此最好的办法是使用let
将它们作为函数体的局部变量:
(defun check-row (row board)
(let ((checkarray (make-array 9)) (result t))
(fill checkarray 0)
(loop for i upto 8 do
(setf (aref checkarray (- (get-element row i board) 1))
(+ (aref checkarray (- (get-element row i board) 1)) 1)))
(loop for i upto 8 do
(if (or (= (aref checkarray i) 0) (> (aref checkarray i) 1))
(setq result nil) ()))
result))
编辑:此外,由于您只是在一个地方添加1,因此您可以使用incf而不是那个长setf:
(defun check-row (row board)
(let ((checkarray (make-array 9)) (result t))
(fill checkarray 0)
(loop for i upto 8 do
(incf (aref checkarray (- (get-element row i board) 1))))
(loop for i upto 8 do
(if (or (= (aref checkarray i) 0) (> (aref checkarray i) 1))
(setq result nil) ()))
result))
答案 1 :(得分:7)
任何未定义的变量都可能被认为是特殊的。另一种解释也没有意义。
你可以
或
或
无论如何,SETQ没有定义或声明变量。它所做的就是将现有变量设置为某个值。
避免在代码中使用SETQ设置未定义/声明的变量。其确切后果在ANSI Common Lisp标准中未定义。
答案 2 :(得分:1)
不同之处在于严格来说,setq不应该用于定义变量(我不确定为什么,因为它 定义变量)。
对全局变量使用defvar
,为本地人使用let
构造。