2009-01-30 40 views
3

任何Common Lisp(內置)函數是否返回2個以上的值?我知道許多返回2,但我想不出一個返回3.任何Common Lisp函數是否返回3個值?

(我看到這裏有關返回超過2個值的評論,並試圖想到CL這樣做的情況,但可以')

回答

4

有一個get-setf-expansion函數。它返回5個值。

7

decode-universal-time返回九個值。

+0

噢,你說得對。我知道。真。 – Ken 2009-02-09 17:57:33

27

是的,存在這樣的功能。下面是在COMMON-LISP封裝,只返回三個值功能的完整列表,如SBCL源代碼中聲明:

COMPILE         required: 3, optional: 0, rest?: NIL 
INTEGER-DECODE-FLOAT     required: 3, optional: 0, rest?: NIL 
COMPILE-FILE       required: 3, optional: 0, rest?: NIL 
GET-PROPERTIES       required: 3, optional: 0, rest?: NIL 
FUNCTION-LAMBDA-EXPRESSION    required: 3, optional: 0, rest?: NIL 
DECODE-FLOAT       required: 3, optional: 0, rest?: NIL 
RENAME-FILE        required: 3, optional: 0, rest?: NIL 

此外,下面的函數返回值更高的恆定數量比三:

DECODE-UNIVERSAL-TIME     required: 9, optional: 0, rest?: NIL 
GET-DECODED-TIME      required: 9, optional: 0, rest?: NIL 

這些函數返回一個可變數目的值,從而有可能多於三個:

NO-APPLICABLE-METHOD     required: 0, optional: 0, rest?: T 
NO-NEXT-METHOD       required: 0, optional: 0, rest?: T 
VALUES         required: 0, optional: 0, rest?: T 

(I've omitted some functions from this list where SBCL does not declare 
a values type explicitly. get-setf-expansion is one of them.) 

列的說明:required是這些函數的返回值的最小數量,optional SBCL認爲可能或可能不會返回的固定數量的返回值,rest?表示預期可變數量的值。 (僅macroexpandmacroexpand-1實際使用&可選的,不要問我爲什麼。)

而只是爲了好玩,這裏是我以前拿出這些表的源代碼:

(do-external-symbols (sym :common-lisp)           
    (when (fboundp sym)               
    (multiple-value-bind (required optional rest)        
     (let ((fun-type (sb-int:info :function :type sym)))      
      (etypecase fun-type             
      (sb-kernel:fun-type             
      (let ((returns              
        (sb-kernel:fun-type-returns fun-type)))      
       (etypecase returns            
       (sb-kernel:values-type           
        (values (length (sb-kernel:values-type-required returns))  
          (length (sb-kernel:values-type-optional returns))  
          (sb-kernel:values-type-rest returns)))     
       (sb-kernel:named-type           
        (if (sb-kernel:named-type-name returns)      
         (values 1 0 t)           
         (values 0 0 nil))))))          
      (t                 
      (values 0 0 t))))             
     (format t                 
       "~A~40Trequired: ~D, optional: ~D, rest?: ~A~%"     
       sym                
       required optional rest))))