2009-02-08 32 views
5

Trong lisp chung tôi đã nhận thấy rằng tôi có thể viết này:Tôi có thể tham khảo các vị trí khác trong hư hỏng không?

(defun foo (&key (a 1) (b 2) (c (+ a b))) (print (+ a b c))) 

Và khi tôi gọi (foo), 6 được in ra. Vì vậy, đối số c có thể tham chiếu đến các giá trị được đặt cho ab. Nhưng tôi không thể tìm cách để làm một cái gì đó tương tự với defstruct. Một cái gì đó như:

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 

Có cách nào để làm điều này không?

Trả lời

7

Bạn có thể thực hiện việc này bằng cách sử dụng tùy chọn :constructor của 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) 

Để biết thêm thông tin, hãy xem mục nhập CLHS cho defstruct.

+0

Ah, điều này có vẻ như những gì tôi đã hy vọng ... cảm ơn! – casper

3

Không phải như vậy. Nhưng sử dụng Lisp thủ đoạn đọc bạn có thể làm:

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

Nếu không sử dụng defclass và chuyên một hàm tổng quát shared-initialize.

Lưu ý rằng các macro trình đọc này sẽ tham chiếu biểu mẫu , không phải kết quả của việc đánh giá nó. Như vậy

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

sẽ làm cho một thing với hai biệt cuộc gọi đến generate-unique-id.

Các vấn đề liên quan