2

除了警告消息外,此代码可以按我的意愿工作。在 GNU Common Lisp 中,如何在不抑制其他可能警告消息的情况下抑制该消息?

 1 (defgeneric zang (x y)
 2   (:documentation "they want you to put documentation here"))
 3 (defmethod zang ((a number) (b string))
 4   (format t "got to zang ((~s number) (~s string))~%" a b))
 5 (defmethod zang ((a integer) (b string))
 6   (format t "got to zang ((~s integer) (~s string))~%" a b)
 7   (when (evenp a)
 8     (format t "passing control to the other guy~%")
 9     (call-next-method (1+ a) "hoo boy")
10     (format t "returned control from the other guy~%")))
11 (defmethod no-applicable-method (zang &rest args)
12   (format t "no applicable method for (zang ~{~s~^ ~})~%" args))
13 (zang 3.5 "hi")
14 (zang 3 "hi")
15 (zang 4 "hi")
16 (zang "hello" "world")
WARNING: Replacing method #<STANDARD-METHOD (#<BUILT-IN-CLASS T>)> in
         #<STANDARD-GENERIC-FUNCTION NO-APPLICABLE-METHOD>
got to zang ((3.5 number) ("hi" string))
got to zang ((3 integer) ("hi" string))
got to zang ((4 integer) ("hi" string))
passing control to the other guy
got to zang ((5 number) ("hoo boy" string))
returned control from the other guy
no applicable method for (zang "hello" "world")

编辑以回应Vatine的友好回复:

我试过了,情况从警告升级为致命错误:

 (defgeneric zang (x y)
   (:documentation "they want you to put documentation here"))
 (defmethod zang ((a number) (b string))
   (format t "got to zang ((~s number) (~s string))~%" a b))
 (defmethod zang ((a integer) (b string))
   (format t "got to zang ((~s integer) (~s string))~%" a b)
   (when (evenp a)
     (format t "passing control to the next guy~%")
     (call-next-method (1+ a) "hoo boy")
     (format t "returned control from the next guy~%")))
 ;(defmethod no-applicable-method (zang &rest args)
 ;  (format t "no applicable method for (zang ~{~s~^ ~})~%" args))
 (defmethod no-applicable-method ((zang eql #'zang) &rest args)
   (format t "no applicable method for (zang ~{~s~^ ~})~%" args))
 (zang 3.5 "hi")
 (zang 3 "hi")
 (zang 4 "hi")
 (zang "hello" "world")
*** - DEFMETHOD NO-APPLICABLE-METHOD: Invalid specialized parameter in method
      lambda list ((ZANG EQL #'ZANG) &REST ARGS): (ZANG EQL #'ZANG)
4

2 回答 2

4

您需要为NO-APPLICABLE-METHOD. 如果您使用编译器(即使是 CLISP 实现也可以通过 COMPILE-FILE 进行编译),您还应该在编译时收到关于不正确参数列表的错误消息。

例如,LispWorks 编译器说:

**++++ Error between functions:
 An argument is not an atom or list of two elements : (ZANG EQL (FUNCTION ZANG))

固定版本:

(defgeneric zang (x y)
   (:documentation "they want you to put documentation here"))
(defmethod zang ((a number) (b string))
   (format t "got to zang ((~s number) (~s string))~%" a b))
(defmethod zang ((a integer) (b string))
   (format t "got to zang ((~s integer) (~s string))~%" a b)
   (when (evenp a)
     (format t "passing control to the next guy~%")
     (call-next-method (1+ a) "hoo boy")
     (format t "returned control from the next guy~%")))
;(defmethod no-applicable-method (zang &rest args)
;  (format t "no applicable method for (zang ~{~s~^ ~})~%" args))

(defmethod no-applicable-method ((zang (eql #'zang)) &rest args)
   (format t "no applicable method for (zang ~{~s~^ ~})~%" args))

例子:

(defun test ()
 (zang 3.5 "hi")
 (zang 3 "hi")
 (zang 4 "hi")
 (zang "hello" "world"))

CL-USER 1 > (test)
got to zang ((3.5 number) ("hi" string))
got to zang ((3 integer) ("hi" string))
got to zang ((4 integer) ("hi" string))
passing control to the next guy
got to zang ((5 number) ("hoo boy" string))
returned control from the next guy
no applicable method for (zang "hello" "world")
NIL
于 2011-12-15T23:17:32.827 回答
3

我想你想在 no-applicable-method 上定义一个方法:

(defmethod no-applicable-method ((zang (eql #'zang)) &rest args)
   ...)

按原样,您正在声明一个适用于所有泛型函数的方法,这就是 clisp 告诉您正在替换已定义方法的原因。

于 2011-12-15T15:38:27.117 回答