在 Common Lisp 中,函数不仅可以返回一个值,还可以返回多个值。比如floor,它会朝零方向向下取整,返回两个值:第一个是取整后的值,第二个是余数。
(floor 3.5) ; => 3
; 0.5
(我们会把返回的多个值分行显示在输出中。)
如果你想让一个函数返回多个值,可以使用values访问器:
(defun three-numbers () (values 1 2 3))
(three-numbers) ; => 1
; 2
; 3
如果你有一组想要返回的值,可以使用value-list:
(values-list '(a b c)) ; => a
; b
; c
如果你只关心第一个值,那不需要做什么特别的事,语言会替你处理好:
(+ (values 1 2 3) (values 10 20 30)) ; => 11
不过,如果你想访问其他那些值,就需要用上几个函数。
两个主要的宏是multiple-value-list和multiple-value-bind。它们用来包裹返回多个值的表达式,并捕获所有的值。第一个会创建一个包含所有值的数组,第二个则让你可以把变量绑定到各个值上。
(multiple-value-list (values 1 2 3)) ; => (1 2 3)
(multiple-value-bind (a b c) (values 1 2 3)
(+ a b c)) ; => 6
注意,变量a、b和c的作用域只在multiple-values-bind内部。
另一个有用的宏是nth-value。它类似于用于数组的nth,同样是从一组多个值中取出第“n”个元素:
(nth-value 0 (values 1 2 3 )) ; => 1
(nth-value 1 (values 1 2 3 )) ; => 2
(nth-value 2 (values 1 2 3 )) ; => 3