Lisp错误处理-检查变量是否为nil



我最近一直在处理一些lisp,我正在编写一个函数,它返回元素的组合。它工作得很好,但它仍然给我一个警告错误>参数Y不是一个数字:NIL

我代码:

(defun printo (x y z)
  (if (and x y z)      
      (format t "~a and ~a  difference: ~a ~%" x y z)
      ))
(defun getDiff (x y)
  (return-from getDiff (abs (- x y))))

(defun distcalc (lista)
  (loop for k from 0 to (list-length lista)
     do (loop for j from 0 to (list-length lista)
       do (let ((pivot (nth k lista))(base (nth j lista)))
        (if (nth j lista)(printo  pivot  base (abs (- base pivot))
                      ))
        ))
       ))
(distcalc '(1 10 20 25 13))

作为这方面的初学者,我想我可能错过了一些错误处理的地方,但是粘液把我扔在错误屏幕上真的很烦人!

谢谢你的帮助

请使用标准格式和命名:

(defun printo (x y z)
  (if (and x y z)
      (format t "~a and ~a  difference: ~a ~%" x y z)))
(defun get-diff (x y)
  (return-from get-diff (abs (- x y))))
(defun distcalc (lista)
  (loop for k from 0 to (list-length lista)
        do (loop for j from 0 to (list-length lista)
                 do (let ((pivot (nth k lista))
                          (base (nth j lista)))
                      (if (nth j lista)
                          (printo pivot base (abs (- base pivot))))))))
(distcalc '(1 10 20 25 13))

如果在if中不需要替代,则使用when:

(defun printo (x y z)
  (when (and x y z)
    (format t "~a and ~a  difference: ~a ~%" x y z)))
(defun get-diff (x y)
  (return-from get-diff (abs (- x y))))
(defun distcalc (lista)
  (loop for k from 0 to (list-length lista)
        do (loop for j from 0 to (list-length lista)
                 do (let ((pivot (nth k lista))
                          (base (nth j lista)))
                      (when (nth j lista)
                        (printo pivot base (abs (- base pivot))))))))
(distcalc '(1 10 20 25 13))

您不需要returnreturn-from;函数体返回最后一种形式的值。我猜你想用你的get-diff:

(defun printo (x y z)
  (when (and x y z)
    (format t "~a and ~a  difference: ~a ~%" x y z)))
(defun get-diff (x y)
  (abs (- x y)))
(defun distcalc (lista)
  (loop for k from 0 to (list-length lista)
        do (loop for j from 0 to (list-length lista)
                 do (let ((pivot (nth k lista))
                          (base (nth j lista)))
                      (when (nth j lista)
                        (printo pivot base (get-diff base pivot)))))))
(distcalc '(1 10 20 25 13))

错误是循环to包含end;你想要below:

(defun printo (x y z)
  (when (and x y z)
    (format t "~a and ~a  difference: ~a ~%" x y z)))
(defun get-diff (x y)
  (abs (- x y)))
(defun distcalc (lista)
  (loop for k from 0 below (list-length lista)
        do (loop for j from 0 below (list-length lista)
                 do (let ((pivot (nth k lista))
                          (base (nth j lista)))
                      (when (nth j lista)
                        (printo pivot base (get-diff base pivot)))))))
(distcalc '(1 10 20 25 13))

但是,您根本不需要索引,因此您可以简单地遍历列表:

(defun printo (x y z)
  (when (and x y z)
    (format t "~a and ~a  difference: ~a ~%" x y z)))
(defun get-diff (x y)
  (abs (- x y)))
(defun distcalc (lista)
  (loop for pivot in lista
        do (loop for base in lista
                 when base
                 do (printo pivot base (get-diff base pivot)))))
(distcalc '(1 10 20 25 13))

我们现在也许可以更好地看到lista中的任何nil s也将是a外循环中的问题:

(defun printo (x y z)
  (when (and x y z)
    (format t "~a and ~a  difference: ~a ~%" x y z)))
(defun get-diff (x y)
  (abs (- x y)))
(defun distcalc (lista)
  (loop for pivot in lista
        when pivot
        do (loop for base in lista
                 when base
                 do (printo pivot base (get-diff base pivot)))))
(distcalc '(1 10 20 25 13))

您的错误是(loop for k from 0 to (list-length lista))将给您k 0-5,而不是0-4(nth 5 '(1 10 20 25 13))会给你nil(- 1 nil)同样的错误。每次都做nth并不好。也许你应该这样做:

(defun distcalc (lista)
  (loop :for pivot :in lista
        :do (loop :for base :in lista
                  :if base
                  :do (printo pivot base (abs (- base pivot))))))

最新更新