【问题标题】:Common lisp values-list functionCommon lisp values-list 函数
【发布时间】:2018-06-17 13:48:21
【问题描述】:

我有这个功能:

(defun call-generic-function (gf &rest args)
    (let* ((applicable-methods (compute-applicable-methods gf  args))
            (most-specific-method (select-next-method-to-call  
                applicable-methods)))
        (print "applicable methods")
        (print (length applicable-methods))  
        (print args)
        (print (values-list args))
        (funcall (method-function most-specific-method)
              (values-list args)         
              (remove most-specific-method applicable-methods))))

我希望 values-list 给我列表 args 的所有元素(这是两个对象,作为三个预期参数中的两个通过 funcall 传递给被调用方法),但它只给出第一个元素我得到一个错误,我只提供 2 个参数而不是预期的 3 个参数。这可以通过以下事实得到证实:(print args) 打印出 2 个对象的列表,但 (print (values-list args)) 仅打印出这些对象中的第一个。我该如何纠正这个问题?

结果(打印参数):

(#S(OBJECT
    :CLASS #S(CLASS
              :DIRECT-SUPERCLASS #S(CLASS
                                    :DIRECT-SUPERCLASS #S(CLASS
                                                          :DIRECT-SUPERCLASS NIL
                                                          :DIRECT-SLOTS NIL)
                                    :DIRECT-SLOTS (NAME ADDRESS))
              :DIRECT-SLOTS (EMPLOYER))
    :SLOTS #<HASH-TABLE :TEST EQL :COUNT 3 {1003932403}>)
 #S(OBJECT
    :CLASS #S(CLASS
              :DIRECT-SUPERCLASS #S(CLASS
                                    :DIRECT-SUPERCLASS NIL
                                    :DIRECT-SLOTS NIL)
              :DIRECT-SLOTS (SPORTS))
    :SLOTS #<HASH-TABLE :TEST EQL :COUNT 1 {1003932853}>)) 

结果(打印(值列表参数))

#S(OBJECT
   :CLASS #S(CLASS
             :DIRECT-SUPERCLASS #S(CLASS
                                   :DIRECT-SUPERCLASS #S(CLASS
                                                         :DIRECT-SUPERCLASS NIL
                                                         :DIRECT-SLOTS NIL)
                                   :DIRECT-SLOTS (NAME ADDRESS))
             :DIRECT-SLOTS (EMPLOYER))
   :SLOTS #<HASH-TABLE :TEST EQL :COUNT 3 {1003932403}>) 

如您所见,values-list 仅获取第一个对象,并使我期望两个对象的函数都失败。

【问题讨论】:

  • 您希望values-list 做什么?
  • 例如,(+ (values-list '(1 2))) 应该给我 3。这是我的想法,但我给了我 1
  • ...它为什么要这样做?我不认为+ 对多值有什么特别的作用。
  • 令我震惊。我在stackoverflow.com/questions/8243813/… 看到它。以为我可以用它实现“ (+ (values-list '(1 2))) = 3”。我可以使用什么来动态检索列表的所有元素并将它们作为单个元素传递给函数?
  • 我想你想要apply,而不是funcall

标签: common-lisp


【解决方案1】:

让我们看看values-list会发生什么:

CL-USER> (values-list '(1 2 3))
1 ;
2
3

此函数接受一个列表并将其项目作为多个值返回。多个值的工作方式是,在大多数情况下,多个值被删除并且只使用第一个值(如果没有返回值,则使用NIL):

CL-USER> (list (values-list '(1 2 3)))
(1)

有多种方法可以使用多个值或调用具有多个参数的函数:

CL-USER> (apply #'list 4 '(1 2 3))
(4 1 2 3)
CL-USER> (multiple-value-call #'list (values 4 5) (values-list '(1 2 3)))
(4 5 1 2 3)

但是请注意,在您的问题中,您似乎想用多个参数调用 print:

CL-USER> (print 1 2)
;; error because 2 is not an output stream

如果要打印列表中的每一项,则可以使用循环或格式:

CL-USER> (loop for item in '(1 2 3) do (print item))
1
2
3
NIL
CL-USER> (format t "~{~a~%~}" '(1 2 3))
1
2
3
NIL

如果你想调用一个中间有任意数量参数的函数,那么:

CL-USER> (apply #'list 1 (append '(1 2) (list 3)))
(1 1 2 3)
CL-USER> (multiple-value-call #'list 1 (values-list '(1 2)) 3)
(1 1 2 3)

但在您的情况下,我认为实际的解决方案是在第一个参数而不是最后一个参数中传递适用方法的列表。

【讨论】:

    猜你喜欢
    • 2017-10-19
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    • 2014-10-24
    相关资源
    最近更新 更多