假设我定义了一个新类foo
:
(defclass foo ()
((bar :initarg :bar ...)
(baz :initarg :baz ...)
...))
我想为foo
创建一个自定义比较器,例如:
(defun foo-equalp (foo1 foo2)
(equalp (bar foo1)))
是否有更好,更明确的方法将此foo-equalp
函数与foo
类绑定?
我在考虑不必将#'foo-equalp
作为:test
参数传递给像REMOVE-DUPLICATES
这样的函数,但即使这是不可能的,我仍然想知道是否有一个更惯用的Lisp方法来定义这个函数。
答案 0 :(得分:3)
如果我理解了您的问题,那么generic functions可以提供帮助
(defgeneric foo-equalp (foo1 foo2))
(defmethod foo-equalp ((foo1 foo) (foo2 foo))
(and (equal (bar foo1) (bar foo2))
(equal (baz foo1) (baz foo2))))
现在当您使用非foo类型的对象调用foo-equalp时,会出现此错误。
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION FOO-EQUALP (1)>
when called with arguments
(1 2).
或者您可能希望其他所有内容都返回
(defmethod foo-equalp ((foo1 t) (foo2 t))
nil)
这里我们专注于t which is the set of all objects。当你调用一个方法时,常见的lisp将始终为参数选择“最接近/最具体”的类型匹配(这是一个可怕的描述错误......我需要更多咖啡,请查看链接,因为它很棒 :))
以下是来自Practical Common Lisp 的片段(链接在此顶部 回答)
泛型函数定义抽象操作,指定其名称 和参数列表,但没有实现。实际执行情况 通用函数的方法由方法提供。
方法表明他们可以处理哪种类型的参数 专门化泛型函数定义的必需参数。
例如,对于通用函数绘制,您可以定义一个方法 专门为作为实例的对象的形状参数 类圈,而另一种方法专门为对象的形状 这是班级三角形的实例。