我如何专门化一个泛型函数来获取指定给定类的子类的符号。 例如:
(defclass a () ())
(defclass b (a) ())
(defclass c (b) ())
(defclass d () ())
(defgeneric fun (param))
(defmethod fun ((param (<subclass of> a)))
(format t "~a is a subclass of A~%" param))
(fun 'c) ;-> "C is a subclass of A"
(fun 'd) ;-> Error: not found method for generic function call (fun 'd)
使用 CLOS 可以进行这种调度吗?如果是,我应该写什么来代替“subclass of”?
最佳答案
请注意,Common Lisp 具有函数 SUBTYPEP
:
CL-USER 15 > (subtypep 'd 'a)
NIL
T
CL-USER 16 > (subtypep 'c 'a)
T
T
请参阅 SUBTYPEP 的文档对于两个返回值的含义(先说是不是子类型)。类也是类型。
这意味着您的功能就是这样:
(defun fun (class-name)
(if (subtypep class-name 'a)
(format t "~a is a subclass of A~%" class-name)
(error "wtf")))
记住:方法中的继承优于类继承。这意味着要使用继承,您必须传递某个类的实例:
(defmethod fun ((param a))
(format t "~a is a subclass of A~%" (class-name (class-of param))))
上面采用类 A
的实例。
调用它:
CL-USER 29 > (fun (make-instance 'a))
A is a subclass of A
NIL
CL-USER 30 > (fun (make-instance 'c))
C is a subclass of A
NIL
CL-USER 31 > (fun (make-instance 'd))
Error: No applicable methods for #<STANDARD-GENERIC-FUNCTION FUN 418001813C>
with args (#<D 40200011E3>)
1 (continue) Call #<STANDARD-GENERIC-FUNCTION FUN 418001813C> again
2 (abort) Return to level 0.
3 Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
CL-USER 32 : 1 >
有一种方法可以简化 ^h^h^h^h^h^h^h^h 使其更容易调用:您可以使用类似 CLOS:FINALIZE- 的方法确保类已完成INHERITANCE
并使用类原型(prototype)作为输入(调用 CLASS-PROTOTYPE
)。这样你就不需要为调度创建类的实例。一个人会只使用原型(prototype)实例。
另一种丑陋的版本是对值进行硬编码:
(defmethod fun0 ((param (eql 'b)))
T)
(defmethod fun0 ((param (eql 'c)))
T)
关于common-lisp - 如何为给定类的子类专门化泛型函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9544137/