2013-06-22 18 views
7

在通常的lisp中,我可以使用什麼來使用槽名/符號訪問結構槽?common lisp:defstruct結構的slot-value

我要的是

(defstruct point (x 0) (y 0))  
(defmacro -> (struct slot) `(slot-value ,struct ,slot)) 

(setf p (make-point)) 
(setf (slot-value p 'x) 1) 
(setf (-> p 'y) 2) 

我使用clozure CL,並在clozure CL這個工程。但是,AFAIK這是非標準行爲(相當於「未定義行爲」C++)。我不打算切換到另一個CL實現,所以我應該繼續使用slot-value作爲結構,還是有更好的方法來做到這一點?

回答

8

通常你會使用存取函數和結構。

您的代碼定義了訪問函數point-xpoint-y。你可以使用這些。

您還可以使用SLOT-VALUE以及支持它的實現上的結構。我想這是大多數實現(GCL將是一個例外)。有一個Lisp軟件,它假定SLOT-VALUE適用於結構。我不認爲實現會刪除對它的支持。這不符合標準,因爲某些實現者不希望在部署的應用程序中提供此功能。

所以兩種方式都可以。

如果你想擁有短名稱,請與存取:各種存取功能之間

CL-USER 109 > (defstruct (point :conc-name) 
       (x 0) (y 0)) 
POINT 

CL-USER 110 > (make-point :x 5 :y 3) 
#S(POINT :X 5 :Y 3) 

CL-USER 111 > (setf p1 *) 
#S(POINT :X 5 :Y 3) 

CL-USER 112 > (x p1) 
5 

CL-USER 113 > (setf p2 (make-point :x 2 :y 3)) 
#S(POINT :X 2 :Y 3) 

CL-USER 114 > (list p1 p2) 
(#S(POINT :X 5 :Y 3) #S(POINT :X 2 :Y 3)) 

CL-USER 115 > (mapcar 'x (list p1 p2)) 
(5 2) 

名稱衝突,那麼就必須通過包裝來防止。

如果你想寫一個更短版本的SLOT-VALUE,那也沒關係。寫一個宏。或者寫一個內聯函數。當然 - 爲什麼不呢?

正如我所說,SLOT-VALUE與大多數實現中的結構一起使用。在這種情況下,您不應該在乎ANSI CL規範沒有定義這一點。在很多方面,實現擴展了ANSI CL規範。例如,通過SLOT-VALUE處理結構,將流實現爲CLOS類,將條件實現爲CLOS類,提供元對象協議...

+0

「您可以使用這些。我知道,但是來自C++的內容很長/很冗長。在C++/C中,你可以通過「。」來訪問字段。或「 - >」。即'點p; p.x = 0;'。所以我想要更短的語法。我定義了「 - >」宏,但發現「插槽值」不應該用於結構上(儘管它在許多實現中起作用)。這就是我問這個問題的原因。 – SigTerm

+0

謝謝,這非常有用/信息豐富。 – SigTerm