在 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