lisp - 删除重复项时将槽值指定为键

标签 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-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) 如果所讨论的插槽有读取器/访问器。


sleep 后编辑:

您也不必费心将 :initform 设置为错误;如果您没有指定默认值并且有人试图读取它,则插槽将默认执行此操作。如果您想要这个错误,您可以执行类似:initform nil 的操作。看看这个优秀的 CLOS tutorial以及chapters 16 and 17 of Practical Common Lisp有关 Common Lisp 中对象的更多信息。

此外,将来如果您有工作代码需要样式建议,请查看 codereview.stackexchange .有少量但活跃的 Lisp 审阅者。

关于lisp - 删除重复项时将槽值指定为键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9050196/

相关文章:

common-lisp - 测试一个符号是否是 Common Lisp 中的 defstruct 名称

emacs - 我怎样才能让粘液在 Windows 上与 clisp 一起工作

lisp - 在 lisp 中展平列表(同时删除 'nil' 并在 ". "之后保留原子)

macos - 在 Mac OS X 上从源代码编译 SBCL

Emacs/普通口齿不清 : Quote variable's value

lisp - Elisp:如何推回列表

arrays - 测试数组是否在 lisp 中的列表中

arrays - Racket:宏输出一些奇怪的东西而不是数组

lisp - 如何在lisp中找到一个类的包?

lisp - 将值插入结构以在不修改结构的情况下进行测试