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))