如何在常见的lisp中处理多个返回

时间:2016-06-05 06:37:09

标签: lisp common-lisp

我有一个返回两个分割列表的函数,如下所示:

>>2016 6 4 12 0

是否有像python一样的常见lisp资源

((1 . 2) (3 . 4) (5 . 7))
((8 . 9) (10 . 23) (30 . 20))

2 个答案:

答案 0 :(得分:11)

有两种选择。首先,您可以使用VALUES返回多个值。然后,您可以使用MULTIPLE-VALUE-BIND将返回值绑定到不同的变量。

(defun foo ()
  (values '((1 . 2) (3 . 4) (5 . 7))
          '((8 . 9) (10 . 23) (30 . 20))))

(multiple-value-bind (a b) (foo)
  (format t "~&A: ~s~%B: ~s~%" a b))
; A: ((1 . 2) (3 . 4) (5 . 7))
; B: ((8 . 9) (10 . 23) (30 . 20))

这与Python略有不同,因为您可以调用该函数,就好像它只返回一个值一样,其他值将被静默丢弃。当第一个值本身有意义时,通常使用多个返回值,其他值只是补充信息(例如参见FLOOR)。

在这种情况下,似乎这两个值彼此相关(因此仅使用第一个值永远不会有意义)。所以在这种情况下,最好返回一个列表或一个cons-cell。您可以使用DESTRUCTURING-BIND将元素分配给变量。

(defun bar ()
  (list '((1 . 2) (3 . 4) (5 . 7))
        '((8 . 9) (10 . 23) (30 . 20))))

(destructuring-bind (a b) (bar)
  (format t "~&A: ~s~%B: ~s~%" a b))
; A: ((1 . 2) (3 . 4) (5 . 7))
; B: ((8 . 9) (10 . 23) (30 . 20))

答案 1 :(得分:3)

如果您已经有两个变量ab,则可以指定值:

CL-USER 6 > (let ((a 10)
                  (b 3))

              (multiple-value-setq (a b) (truncate a b))

              (list a b))
(3 1)

或者使用SETF

CL-USER 7 > (let ((a 10)
                  (b 3))

              (setf (values a b) (truncate a b))

              (list a b))
(3 1)