Frage

Ich möchte verschiedene Felder einer Struktur setf auf eine bestimmte Variable abhängig. Ich beschloss, den folgenden Ansatz zu verwenden:

Erstellen Sie eine Zeichenkette mit dem Accessor Name Feld:

(setq my-string (format nil "STRUCT-ESTADISTICAS-NUM-~S" x))

und dann intern die Verwendung mit FUNCALL:

(funcall (intern my-string) *estadisticas*)

Dieser Aufruf gibt den richtigen Wert des Feldes Struktur, aber wenn ich setf versuchen, diesen Wert zu ändern, es beschwert ich sagen:

(setf (funcall(intern my-string) *estadisticas*) 0)
Error: `(SETF FUNCALL)' is not fbound

kann ich verstehen, warum es nicht funktioniert, aber ich kann nicht einen Weg die Struktur der Felder finden zu ändern. Irgendeine Idee? Danke.

War es hilfreich?

Lösung

Sie möchten über ihren Namen ein Schriftsteller Funktion der Struktur nennen, und der Name des Autors ist die Liste (setf accessor-name); so

(funcall (fdefinition (list 'setf (intern my-string))) 0 estadisticas)

Edit:

Nicht den Rest des Codes zu sehen, ist es schwer zu ergründen, was falsch gelaufen ist. Auf SBCL Dies funktioniert für mich:

(defstruct point x y)
(let ((point (make-point :x 1 :y 2)))
  (funcall (fdefinition (list 'setf (intern "POINT-X"))) 10 point)
  point)

Die oben auswertet zu

#S(POINT :X 10 :Y 2),

wie erwartet.

Andere Tipps

Motivation:

Strukturen sind eine relativ niedrige Ebene Möglichkeiten. ‚Speed‘ war ein wichtiges Entwicklungsziel. Indirection über Schreiber Funktionen nicht durch den Standard unterstützt (wie ich es gelesen). Heute Verwendung CLOS als Standard, es sei denn, man braucht eine bessere Effizienz der Strukturen (schneller lesen und Schreiben von Slots mit Strukturen sind manchmal möglich).

First - Stil:

Verwenden Sie INTERN nicht, verwenden FIND-SYMBOL. Geben Sie auch das Paket, sonst FIND-SYMBOL den Laufzeitwert von * Paket * als Paket verwenden

Second - DEFSTRUCT

Wenn ich die ANSI CL Standard richtig gelesen, ist es nicht, dass DEFSTRUCT schafft Schreiber Funktionen für Slots wie DEFCLASS tut.

CL-USER 24 > (defstruct foo bar baz)
FOO

CL-USER 25 > #'(setf foo-bar)

Error: Undefined function (SETF FOO-BAR) in form (FUNCTION (SETF FOO-BAR)).

So konstruieren einen solchen Namen (SETF FOO-BAR) und versuchen, eine Funktion zu finden, dass fehlschlagen, da eine solche Funktion gibt es keine von der DEFSTRUCT definiert.

Das in Benutzercode (setf (foo-bar some-Struktur) 42) arbeitet, basiert auf definierten SETF Erweiterungen von DEFSTRUCT vorgesehen, aber nicht auf definierten SETF Accessorfunktionen.

Einige Schriftsteller bieten Common Lisp-Implementierungen können Funktionen als Nicht-Standard-Erweiterung zu ANSI CL.

Mögliche Lösungen :

eine Verwendung CLOS Klassen), DEFCLASS tut, was Sie wollen

b) schreiben die Verfasser Funktionen selbst

(defun (setf foo-bar) (new-value struct)
   (setf (foo-bar struct) new-value))

(funcall (fdefinition '(setf foo-bar)) 300 *foo*)

Vor funktioniert dann.

c) (SETF SCHLITZ-VALUE) -. Ein anderes Nicht-Standard-Feature von einigen Implementierungen

Bei einigen Implementierungen von Common Lisp das funktioniert nicht nur für CLOS Klassen, sondern auch für die Strukturen:

(setf (slot-value some-struct 'bar) 42)

Ich bin mir nicht sicher, ob Allegro CL unterstützt, die, aber das wäre leicht herausfinden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top