Lisp 删除重复项时将插槽值指定为键

Lisp 删除重复项时将插槽值指定为键,lisp,common-lisp,clisp,clos,Lisp,Common Lisp,Clisp,Clos,以下代码符合我的要求: 1 (defclass some-class () 2 ((some-slot 3 :initarg :somearg 4 :initform (error ":somearg not specified")))) 5 (defparameter *alpha* (make-instance 'some-class :somearg 3)) 6 (defparameter *beta* (make-instance 'some-c

以下代码符合我的要求:

 1 (defclass some-class ()
 2   ((some-slot
 3       :initarg :somearg
 4       :initform (error ":somearg not specified"))))
 5 (defparameter *alpha* (make-instance 'some-class :somearg 3))
 6 (defparameter *beta*  (make-instance 'some-class :somearg 5))
 7 (defparameter *gamma* (make-instance 'some-class :somearg 3))
 8 (princ (slot-value *beta* 'some-slot)) (terpri)
 9 (defparameter *delta* (list *alpha* *beta* *gamma*))
10 (princ *delta*) (terpri)
11 (princ (remove-duplicates *delta*
12          :test #'equal
13          :key (lambda (x) (slot-value x 'some-slot))))
14 (terpri)
5
(#<SOME-CLASS #x21C1D71E> #<SOME-CLASS #x21C1DAFE> #<SOME-CLASS #x21C1DC3E>)
(#<SOME-CLASS #x21C1DAFE> #<SOME-CLASS #x21C1DC3E>)

您可以尝试
:reader
:accessor

应该允许您将第11行到第13行重写为

(princ (remove-duplicates *delta* :test #'equal :key #'some-slot))
也就是说,
(某个插槽x)
相当于
(插槽值x'某个插槽)
,前提是该插槽具有读卡器/存取器


睡眠编辑后:

您也不需要费心将
:initform
设置为错误;默认情况下,如果您没有指定默认值,并且有人试图读取该值,插槽将执行此操作。如果不希望出现错误,可以执行类似于
:initform nil
的操作。查看这篇优秀的文章,以及有关CommonLisp中对象的更多信息


另外,将来如果你有你想要的风格建议的工作代码,一定要查看。Lisp审阅者人数虽少,但仍很活跃。

您可以为
defclass
中的插槽定义一个读卡器函数,并将其作为
删除重复项的关键函数提供。例如,将此行添加到插槽定义中:

:reader some-slot
然后在调用
删除重复项时使用此选项:

:key #'some-slot

Inaimathi,我将:initform设置为error的原因不是在访问插槽时触发错误,而是在创建对象之前触发错误。“这对我有用吗?”比尔-啊,我明白了。否,默认行为是在访问未设置的插槽时出错。那你就明白了。
:reader some-slot
:key #'some-slot