2013-06-22 12 views
7

Im allgemeinen lisp, was kann ich verwenden, um mit Hilfe des Slot-Namens/-Symbols auf den Struktur-Slot zuzugreifen?common lisp: slot-value für defstruct structures

Was ich will, ist

(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) 

I Clozure cl bin mit, und in Clozure cl das funktioniert. Bei AFAIK handelt es sich jedoch um ein Nicht-Standard-Verhalten (äquivalent zu "undefiniertem Verhalten" C++). Ich plane nicht, zu einer anderen CL-Implementierung zu wechseln, also sollte ich weiterhin slot-value für Strukturen verwenden, oder gibt es einen besseren Weg dazu?

Antwort

8

Normalerweise würden Sie Accessor-Funktionen mit Strukturen verwenden.

Ihr Code definiert die Accessor-Funktionen point-x und point-y. Sie können diese verwenden.

Sie können auch SLOT-VALUE mit Strukturen auf Implementierungen verwenden, die es unterstützen. Ich denke, das sind die meisten Implementierungen (GCL wäre eine Ausnahme). Es gibt Lisp-Software, die davon ausgeht, dass SLOT-VALUE für Strukturen funktioniert. Ich denke nicht, dass Implementierungen die Unterstützung dafür entfernen werden. Im Standard ist dies nicht der Fall, da einige Implementierer diese Funktionalität in bereitgestellten Anwendungen nicht bereitstellen möchten.

Also beide Wege sind in Ordnung.

Wenn Sie kurze Namen haben wollen, gehen mit Accessoren:

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) 

Namenskonflikte zwischen verschiedenen Accessorfunktionen müsste dann durch ein Paket zu verhindern.

Wenn Sie eine kürzere Version von SLOT-VALUE schreiben möchten, ist das auch in Ordnung. Schreibe ein Makro. Oder schreibe eine Inline-Funktion. Sicher warum nicht? Wie gesagt, funktioniert SLOT-VALUE in den meisten Implementierungen mit Strukturen. In diesem Fall sollten Sie nicht darauf achten, dass die ANSI CL-Spezifikation dies nicht definiert. In vielerlei Hinsicht erweitern Implementierungen die ANSI CL-Spezifikation. Zum Beispiel durch SLOT-VALUE Arbeiten an Strukturen, Implementieren von Datenströmen als CLOS-Klassen, Implementieren von Bedingungen als CLOS-Klassen, Bereitstellen eines Meta-Objekt-Protokolls, ...

+0

"Sie können diese verwenden." Ich weiß das, aber von C++ kommend, das ist irgendwie lang/ausführlich. In C++/C greifen Sie über "." Auf Felder zu. oder "->". I.e. 'Punkt p; p.x = 0; '. Also wollte ich kürzere Syntax. Ich habe Makro "->" definiert, aber herausgefunden, dass "slot-value" nicht für Strukturen verwendet werden soll (obwohl es in vielen Implementierungen funktioniert). Deshalb habe ich die Frage gestellt. – SigTerm

+0

Danke, das war sehr nützlich/informativ. – SigTerm