Methods 调用下一个最具体的方法无效

Methods 调用下一个最具体的方法无效,methods,parameters,common-lisp,clos,Methods,Parameters,Common Lisp,Clos,考虑类帐户: (defclass account () ((name :initarg :name :reader name) (balance :initarg :balance :initform 0.00 :accessor balance) (interest-rate :allocation :class :initform 0.06 :reader interest-rate))) 对于此类,我们定义了一个方法draw: (def

考虑类
帐户

(defclass account ()
  ((name :initarg :name :reader name)
   (balance :initarg :balance :initform 0.00 :accessor balance)
   (interest-rate :allocation :class :initform 0.06
                  :reader interest-rate)))
对于此类,我们定义了一个方法
draw

(defmethod withdraw ((acct account) amt)
  (if (< amt (balance acct))
      (decf (balance acct) amt)
      'insufficient-funds))
对于此类,方法
撤销

(defmethod withdraw ((acct password-account) amt pass)
  (if (equal (password acct) pass)
      (call-next-method acct amt )
      'wrong-password))
但这会产生一个错误:

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

Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [*ABORT] Return to SLIME's top level.
 2: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1005308033}>)
泛型函数
#
获取2个必需参数;被要求找到一种与
专家
(#
#1=# #1#)
[SB-PCL类型的条件::FIND-METHOD-LENGTH-MISMATCH]
另见:
Common Lisp Hyperspec,FIND-METHOD[:函数]
重新启动:
0:[重试]重试SLIME REPL评估请求。
1:[*中止]返回SLIME的顶层。
2:[中止]中止线程(#)
为什么会这样?这是什么

被要求找到一个具有专门化器的方法

你是说这里

这里,主要的
draw
函数有两个参数
acct
amt
,因此为了从更具体的方法调用它,它使用3个参数而不是2个参数,我们可以使用不太具体的
draw
方法的参数提供
callnext方法
。但这仍然不起作用。

感谢您的帮助。

通用函数的全等lambda列表

泛型函数的方法需要有lambda列表。语言标准描述了这意味着什么:

正如你所看到的,第一条规则说:

  • 每个lambda列表必须具有相同数量的必需参数
所需参数告诉我们必须始终提供哪些参数。泛型函数还允许可选参数、关键字参数和rest参数。但是没有关于这些的消息。分派只对所需的参数和所有这些参数起作用

拥有相同数量的必需参数使分派更容易,并允许编译器检查参数数量错误的函数调用

可选参数也需要一致

还要注意,泛型函数的所有方法都需要具有相同数量的可选参数。参见标准中的第二条规则

措辞

  • 参数类似于lambda列表中的命名变量
  • 参数是在函数调用中提供的
示例:

(defun foo (a b) (list a b))
a
b
是函数
foo
的参数

(foo (+ 2 3) (* 4 5))

5
20
是函数调用的两个参数
foo

在同一个泛型函数中,不能有一个方法具有两个必需参数,另一个方法具有三个必需参数。CLOS不允许这样。第一个方法定义确定所需参数的数量。示例中的泛型函数有两个必需参数,您尝试用三个必需参数定义一个方法。这是不支持的,也是不允许的。谢谢@RainerJoswig。不支持这种方法有什么特别的原因吗?通过带参数的
callnextmethod
调用下一个最具体的方法有什么意义?因为所有方法都需要相同数量的参数。(因此参数相同)泛型函数需要一个有效数量的必需参数。如果不是这样,编译器将无法检查是否提供了正确数量的必需参数。不,不是所有方法都需要相同数量的参数。所需要的只是这些方法具有相同数量的必需参数。方法可以有其他参数:可选参数、关键字参数、rest参数。
(foo (+ 2 3) (* 4 5))