In Common Lisp gelten Strukturen als starre und Low-Level-Datensätze. Sie haben keine ausgefallenen dynamischen Eigenschaften.
Was Sie mit Strukturen tun können, ist einen neuen Strukturtyp zu definieren, der von einem anderen erbt. Es gibt eine einzige Vererbung verfügbar.
Um dynamische Erweiterbarkeit zu handhaben, ist es eine typische Methode, einer Struktur einen Eigenschaftenlisten-Slot hinzuzufügen. Siehe die Antwort von Joshua.
Dann gibt es das Common Lisp Object System, das mehrere Vererbung bietet und Sie können Klassen zur Laufzeit ändern. Sie können also einer Klasse einen Slot hinzufügen und die Instanzen dieser Klasse selbst aktualisieren. Sie können auch die Klasse eines Objekts ändern und die Slots können hinzugefügt oder gelöscht werden. In der Regel haben alle Instanzen einer Klasse dieselbe Anzahl von Slots. Auch hier sieht man, dass ein Slot mit einer Eigenschaftsliste hinzugefügt und für die Erweiterbarkeit verwendet werden kann.
Es gibt andere Objektsysteme für Common Lisp, die einfach Slots auf einer Instanz pro Instanz hinzufügen können. Aber es ist normalerweise zu viel, um sie nur dafür zu verwenden, da sie ein bisschen leistungsfähiger sind.
Mit CLOS und dem Meta-Objekt-Protokoll kann man versuchen, es zu verstecken.Hier bin ich mit LispWorks:
Wir definieren eine mixin Klasse für unsere Eigenschaften:
(defclass property-mixin()
((plist :initform nil))
#+lispworks
(:optimize-slot-access nil))
Einstellen und Lesen der Eigenschaften:
(defmethod set-property ((object property-mixin) key value)
(setf (getf (slot-value object 'plist) key) value))
(defmethod get-property ((object property-mixin) key)
(getf (slot-value object 'plist) key))
Jetzt schreiben wir Methoden SLOT-VALUE
akzeptieren unser Eigentum Namen zu machen :
(defmethod (setf clos:slot-value-using-class)
(value (class standard-class) (object property-mixin) slot-name)
(declare (ignorable class))
(if (slot-exists-p object slot-name)
(call-next-method)
(progn
(set-property object slot-name value)
value)))
(defmethod clos:slot-value-using-class ((class standard-class)
(object property-mixin)
slot-name)
(declare (ignorable class))
(if (slot-exists-p object slot-name)
(call-next-method)
(get-property object slot-name)))
Beispiel. Wir definieren ein Auto-Klasse mit zwei Steckplätze:
(defclass automobile (property-mixin)
((company :initarg :company)
(motor :initarg :motor))
#+lispworks
(:optimize-slot-access nil))
nun ein Beispiel:
CL-USER 45 > (setf a6 (make-instance 'automobile :company :audi :motor :v6))
#<AUTOMOBILE 402005B47B>
Wir können einen normalen Schlitzwert erhalten:
CL-USER 46 > (slot-value c1 'motor)
:V6
Lassen Sie uns zu einem Schlitz schreiben, das nicht der Fall ist vorhanden, aber wird zu unserer Eigentumsliste hinzugefügt:
CL-USER 47 > (setf (slot-value a6 'seats) 4)
4
Wir können den Wert zurück:
CL-USER 48 > (slot-value c1 'seats)
4
Danke, das ist fast genau das, was ich suche. Aber gibt es eine Möglichkeit, die Eigenschaft, wie Sie es nennen, nur als andere Slots im Knoten zu haben? Mit anderen Worten, gibt es eine Möglichkeit zu tun? (Make-node 'some-label: eins 1: zwei 2) => (SOME-LABEL: ONE 1: TWO 2) ', statt' (SOME-LABEL (: EINS 1: ZWEI 2)) '? –
Kurz gesagt, nein. [Rainers Antwort] (http://stackoverflow.com/a/17556349/1281433) geht im Allgemeinen auf Strukturen ein, aber der Punkt ist, dass Strukturen eine feste Anzahl von Slots haben. Obwohl Sie 'defstruct' verwenden können, um mit der Option' (: type list) ''Arrow-man's records' zu erstellen, haben Sie immer noch nur eine feste Anzahl von Slots (das heißt, die Liste hat eine feste Anzahl von Elemente). Es klingt wirklich so, als wolltest du nur eine Eigenschaftsliste. –
Ja, wenn ich Rainers Antwort lese, denke ich, dass das mehr Feuerkraft ist, als ich für das brauche, was ich tue. Danke für den Rat, Jungs! –