Common lisp 我可以引用defstruct中的其他插槽吗?

Common lisp 我可以引用defstruct中的其他插槽吗?,common-lisp,Common Lisp,在common lisp中,我注意到我可以这样写: (defun foo (&key (a 1) (b 2) (c (+ a b))) (print (+ a b c))) 当我调用(foo),就会打印6。因此,参数c可以引用为a和b设置的值。但是我似乎找不到一种方法来使用defstruct做类似的事情。比如: CL-USER> (defstruct thing a b c) THING CL-USER> (setq q (make-thing :a 1 :b 2 :c (

在common lisp中,我注意到我可以这样写:

(defun foo (&key (a 1) (b 2) (c (+ a b))) (print (+ a b c)))
当我调用
(foo)
,就会打印
6
。因此,参数
c
可以引用为
a
b
设置的值。但是我似乎找不到一种方法来使用
defstruct
做类似的事情。比如:

CL-USER> (defstruct thing a b c)
THING
CL-USER> (setq q (make-thing :a 1 :b 2 :c (+ a b)))
; Evaluation aborted
CL-USER> (setq q (make-thing :a 1 :b 2 :c (+ :a :b)))
; Evaluation aborted

有办法做到这一点吗?

没有办法。但使用Lisp reader技巧可以做到:

(make-thing :a #1=1 :b #2=2 :c (+ #1# #2#))
否则,使用
defclass
并专门化通用函数
sharedinitialize

请注意,这些读卡器宏将引用表单,而不是对表单求值的结果。因此

(make-thing :id #1=(generate-unique-id) :my-id-is #1#)

将通过两个不同的调用来生成一个
对象
生成唯一id

您可以使用
defstruct的
:constructor
选项来完成此操作

CL-USER> (defstruct (thing
                      (:constructor make-thing (&key a b (c (+ a b)))))
           a b c)
THING
CL-USER> (make-thing :a 1 :b 2)
#S(THING :A 1 :B 2 :C 3)
有关更多信息,请参阅的CLHS条目