在阅读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/

10-09 00:10