删除重复
问题描述:
下面的代码时指定一个槽值作为重点做什么,我想:删除重复
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>)
但是,有没有办法做到这一点,而无需编写第13行的功能?有没有一种简捷的方式来指定类实例中的槽值?
当然,以下是语法错误,但它给出了我正在寻找的东西的一般概念。
1 (princ (remove-duplicates *delta*
2 :test #'equal
3 :key '(slot-value 'some-slot)))
4 (terpri)
*** - FUNCALL: (SLOT-VALUE 'SOME-SLOT) is not a function name; try using a
symbol instead
答
您可以试试:reader
或:accessor
。
做
(defclass some-class()
((some-slot
:initarg :somearg :reader some-slot
:initform (error ":somearg not specified"))))
应该让你重新写线11到13,
(princ (remove-duplicates *delta* :test #'equal :key #'some-slot))
也就是说,(some-slot x)
相当于(slot-value x 'some-slot)
如果有问题的插槽中有一个读/存取。
后睡眠编辑:
您也不必费心设置:initform
错误;如果您不指定默认值并且有人试图读取它,则插槽将默认执行此操作。如果你不要想要这个错误,你可以做一些类似于:initform nil
的事情。查看这个出色的CLOS tutorial以及chapters 16 and 17 of Practical Common Lisp了解关于Common Lisp中对象的更多信息。
此外,如果您有工作代码需要样式建议,请检查codereview.stackexchange。 Lisp评论员人数不多,但活跃。
答
您可以为defclass
中的插槽定义阅读器功能,并将其作为remove-duplicates
的关键功能。例如,该行添加到狭槽定义:
:reader some-slot
然后在remove-duplicates
在呼叫时使用这样的:
:key #'some-slot
Inaimathi,我设置的原因:在initForm错误是触发一个错误不当插槽被访问时,但更早,当对象被创建时。这是为我做的吗? – 2012-01-31 05:25:08
@Bill - 啊,我明白了。不,默认行为是在访问未设置的插槽时发生错误。你知道了。 – Inaimathi 2012-01-31 13:33:01