为什么此代码不会打印出数组的内容 -
(defun loopfn (state) (loop for x from 0 to 2 do (loop for y from 0 to 2 do (aref state x y))))
这里我传递的是一个像这样构建的3x3矩阵 -
`(setq i (make-array '(3,3) :initial-contents '((0 1 3) (4 2 5) (7 8 6))))`
我正在打电话 - (loopfn i)
编辑-------- @格雷格 感谢您指出了这一点... 我有以下问题.. 为什么打印输出......
(defun loopfn ()
(loop for x from 0 to 3 do
(if (eq x 2)(return (list x)))))
这在哪里打印出来......
(defun loopfn ()
(loop for x from 0 to 2 do
(loop for y from 0 to 2 do
(if (eq x 2)(return (list x y))))))
我正在打电话
(loopfn)
答案 0 :(得分:2)
您的代码不会打印任何内容。这也是你想要的 - 通常。
但是你希望函数返回一些有用的东西。
因此,您需要了解打印与REPL打印返回值之间的区别。
CL-USER > 3
3
以上返回3. Read-Eval-Print-Loop打印返回值。
CL-USER > (print 3)
3
3
上方打印newline
,然后打印3
两倍。为什么?
第一个是PRINT
调用的副作用,它打印换行符然后打印其参数。
第二个是REPL打印返回值。
另请注意,EQ
不适用于数字比较。请改用EQL
。
请参阅:http://www.lispworks.com/documentation/lw50/CLHS/Body/f_eql.htm
答案 1 :(得分:2)
关于您的第二个问题,(return ...)
相当于(return-from NIL ...)
,因此您只需从内部LOOP
返回外部[11]> (defun loopfn ()
(loop for x from 0 to 2 do
(loop for y from 0 to 2 do
(if (= x 2) (return-from loopfn (list x y))))))
[12]> (loopfn)
(2 0)
。请改用:
[36]> (defun loopfn ()
(loop for x from 0 to 2 nconc
(loop for y from 0 to 2
if (= y 2)
collect (list x y))) )
LOOPFN
[37]> (loopfn)
((0 2) (1 2) (2 2))
另一种可能性是收集比一个更多的值,如
{{1}}
答案 2 :(得分:1)
这在this forum topic中得到了很好的介绍。
外部循环没有会导致返回值的子句。
该线程的一些代码示例:
(defun print-2d-array-as-table (array)
(loop for i from 0 below (array-dimension array 0)
do (loop for j from 0 below (array-dimension array 1)
do (princ (aref array i j))
(if (= j (1- (array-dimension array 1)))
(terpri)
(princ #\Space)))))
和一个循环:
(defun print-2d-array-as-table (array)
(loop for i below (array-total-size array) do
(if (zerop (mod i (array-dimension array 0)))
(terpri)
(princ #\Space))
(princ (row-major-aref array i))))
答案 3 :(得分:1)
您对aref
的调用是获取指定的元素,但您没有对其进行任何操作。您可以将其粘贴到列表中,然后返回:
(defun loopfn (state)
(let ((result '()))
(loop for x from 0 to 2 do
(loop for y from 0 to 2 do
(setf result (cons (aref state x y) result))))
result))
或者你可以把它打印出来:
(defun loopfn (state)
(loop for x from 0 to 2 do
(loop for y from 0 to 2 do
(format t "~a~%" (aref state x y)))))
前者更有用;你想要返回可以进一步处理的东西,并且会为你打印传递到顶层的任何内容。
只要您使用LOOP
,就可以轻松地使用COLLECT
,APPEND
等来收集您的价值观,这是执行此操作的惯用方式。
答案 4 :(得分:0)
对于第二个问题,在未打印的循环中,(eq x 2)
永远不会成立。您已将循环范围从0 to 3
修改为0 to 2
,因此x
永远不会达到2
。由于没有执行明确的(return ...)
,该函数返回nil
。