4

在普通的 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

有没有办法做到这一点?

4

2 回答 2

6

您可以使用:constructor的选项来执行此操作defstruct

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)

For more info, see CLHS entry for defstruct.

于 2009-02-09T09:10:13.463 回答
3

不是那样的。但是使用 Lisp 阅读器技巧,您可以做到:

(make-thing :a #1=1 :b #2=2 :c (+ #1# #2#))

否则使用defclass并专门化泛型函数shared-initialize

请注意,这些阅读器宏将引用表单,而不是评估它的结果。因此

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

将对 athing进行两次不同的调用generate-unique-id

于 2009-02-08T14:36:47.230 回答