【发布时间】: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