首页 > 解决方案 > 不同的初始化,Common Lisp

问题描述

我可以在 CL 中模仿不同的构造函数吗?

详细说明——在 C++ 中,我可以根据传递的参数为同一个类创建不同的构造函数。

我可以用 CLOS 做到这一点吗?可能有不同initialize-instance的 s 关键参数或类似的东西?

标签: classlispcommon-lisp

解决方案


一种方法是使用辅助初始化方法:

(defclass myclass ()
  ((s1 :initarg :s1 :accessor s1)))

(defgeneric initialize-myclass (dispatch class &key))

(defmethod initialize-instance :after ((c myclass) &rest args &key (dispatch 'normal)
                                       &allow-other-keys)
  (apply #'initialize-myclass dispatch c args))

(defmethod initialize-myclass ((dispatch (eql 'normal)) (class myclass) &key))

(defmethod initialize-myclass ((dispatch (eql 'special)) (class myclass)
                               &key x &allow-other-keys)
  (print x))

现在你可以说

(make-instance 'myclass :dispatch 'special ...)

例如。请注意,这不一定是一种好方法,但它确实有效,而且我已经使用过。另请注意,我可能将关键字参数默认设置为错误:我不记得您需要说&allow-other-keys的地方和不需要说的地方,以及说它的正确位置。

这里的基本问题是我们想要一个额外的东西来分派:initialize-instance可以在被定义的对象的类上分派,但这就是它可以分派的全部。特别是它不能调度它的一个关键字参数,因为你不能在 CLOS 中这样做。但是我们可以将其关键字参数之一(dispatch此处)作为位置参数“祝福”到辅助初始化通用函数,然后可以在该参数上调度。


推荐阅读