在阅读Keene的书时,我注意到defgeneric
具有:method
选项,这似乎允许您在通用定义本身中指定方法。我见过的大多数文档都在单独的defmethod
中定义了所有适用的方法。 hyperspec具有通常的清晰度,列出了:method
作为defgeneric
的选项,但并未说明其含义。:method
选项是否提供一个默认值,或者至少提供您期望的最常见用例的文档,或者它具有其他语义?作为样式点,如果您只希望定义一种方法,那么以defgeneric
形式(如果可以,的确可以)或以defmethod
形式进行定义是否更有意义?还是在这种情况下根本没有通用函数,而是使用常规defun
有意义吗?
最佳答案
实际上,HyperSpec entry for defgeneric具有通常的清晰度,准确地说明了其含义。它说defgeneric的语法是:
然后说方法描述的语法是:
然后描述方法组合:
因此:method形式用于定义通用函数上的方法,就像 defmethod 形式一样。
(我同意这并没有真正说明您为什么偏爱defgeneric plus:method而不是defmethod。请记住,Common Lisp中的 Common 意味着该语言是试图统一许多现有的Lisp实现也许有些支持:method,而另一些支持defmethod,这是提供统一接口(interface)的最简单方法。)
也就是说,以下内容将具有相同的效果:
(defgeneric to-list (object))
(defmethod to-list ((object t))
(list object))
(defmethod to-list ((object list))
object)
(defgeneric to-list (object)
(:method ((object t))
(list object))
(:method ((object list))
object))
有时,与反定义形式一起定义某些方法会很方便。这更多的是风格问题,这涉及到您问题的其他部分。
如果您定义的方法没有类型说明符,或者具有适用于每个对象的类型说明符(例如 t ),则它可能是一种默认设置。
我认为这取决于您为什么只希望定义一种方法。如果是因为您只是在定义一个默认值,但是希望其他用户在其上实现方法,那么如果有人需要查找源代码,则将这些方法与defmethod一起使用可能会很方便。如果您只希望做一件事,那么正常的功能可能更有意义。我认为这些决定只能归结为款式选择。
还值得注意的是,还有其他形式可以定义泛型函数的方法(以及其他可以产生泛型函数的形式)。在HyperSpec中,使用向上箭头转到更高的部分通常可以带您更多的散文。在这种情况下,7.6.1 Introduction to Generic Functions是有用的:
关于common-lisp - :method option in defgeneric的使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29639620/