【问题标题】:"Overloading" CLOS multimethods With Different Parameter Lists使用不同的参数列表“重载”CLOS 多方法
【发布时间】:2014-03-20 16:17:49
【问题描述】:

我正在尝试在 Common Lisp 中对多方法进行“重载调用”。以下是案例的简化概要:

(defclass foo ()
  ((slotty :accessor slotty :initarg :slotty)))

(defclass bar ()
  ((slotty :accessor slotty :initarg :slotty)))

(defparameter *foo* (make-instance 'foo :slotty "defnoodle"))
(defparameter *bar* (make-instance 'bar :slotty "Chocolate"))

(defmethod contrived ((f foo) (b bar))
  (format t "i pity the foo ~A, who has a bar ~A ~%" (slotty f) (slotty b)))

(contrived *foo* *bar*)

输出:i pity the foo defnoodle, who has a bar Chocolate

但是一旦我尝试定义下一个方法:

 (defmethod contrived ((f foo))
    (format  t "i just pity the foo ~A ~%" (slotty f)))

CL生气了:

; The generic function #<STANDARD-GENERIC-FUNCTION CONTRIVED (1)>
; takes 2 required arguments; was asked to find a method with
; specializers (#<STANDARD-CLASS FOO>)
;   [Condition of type SB-PCL::FIND-METHOD-LENGTH-MISMATCH]
; See also:
;  Common Lisp Hyperspec, FIND-METHOD [:function]

有谁知道我在这里做错了什么?我知道初始化实例具有类似的灵活性,因为应该能够识别每个类和任意数量的参数的 n 个初始化实例方法。

(defmethod initialize-instance :after ((f foo) &key)
  ())

但我不清楚如何将其转换为我上面给出的香草示例。而且我觉得我可能会叫错树,因为这是 MOP 的一部分。

【问题讨论】:

  • 那不是超载。重载意味着同名符号的早期(编译时)绑定。 CLOS 所做的是 dispatch,即后期(运行时)绑定。如果您有不同数量的参数,则无需将其推迟到运行时。限制是您不能拥有多个具有相同完全限定名称的通用函数。

标签: lisp common-lisp clos


【解决方案1】:

泛型函数的所有方法都必须有一个全等的参数列表。如果您具有相同数量的必需参数、相同数量的可选参数并且以兼容的方式使用&amp;rest 和&amp;key,则参数列表是一致的。

但是,当然,您不能专注于 &amp;optional、&amp;rest 或 &amp;key 参数的类型。

【讨论】:

    【解决方案2】:

    你写道:有谁知道我在这里做错了什么?

    明确一点:CLOS 不支持。在单个泛型函数的方法的方法参数列表中,您不能有不同数量的必需参数。调度只对所需的参数起作用。 Common Lisp 不支持“重载”。

    INITIALIZE-INSTANCE 使用以下语法定义:

    initialize-instance instance &rest initargs &key &allow-other-keys => instance
    

    所有方法都采用一个必需的参数,即实例。调度只在这个对象上完成。然后它允许各种关键字参数 - 不为它们进行分派。

    因此,您需要就泛型函数应采用的所需参数的数量达成一致,并在代码中以这种方式调用它。

    有关规则,请参阅 CL Hyperspec:Congruent Lambda-lists for all Methods of a Generic Function。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      • 2014-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多