2009-11-05 6 views
7

Ich bin eine Klasse für einige Arbeit an molekularen Dynamik bilden, wie folgt:Wann wird ein Initform verwendet?

(defclass %atom (particle) 
    ((name :initarg :name :initform (error "Every atom in the system must have a name!")) 
    (mass :accessor mass :initarg :mass :initform (getmass name)) 
    (charge :accessor charge :initarg :charge :initform (getcharge name)))) 

Anfangs dachte ich, dass ich irgendwie zu anderen Slots innerhalb der Klassendefinition mit einem Initform dh (getmass Name) beziehen könnte - aber das erweist sich als unwahr (oder tut es?!?). Stattdessen wurde mir gesagt, dass Initialize-Instanz der Platz wäre, um all diese Initialisierungs-Sachen zu platzieren ... fair genug.

Die Frage, die ich habe, ist dann wann ist: initform verwendet? Was ist die idiomatische Präferenz? Ich habe gesehen, wie es oben für die Erzeugung von (Fehler "...") Code verwendet wurde, und auch um Standardargumente zu initialisieren, wenn ein: initarg nicht zur Verfügung gestellt wird. Aber beide könnten leicht in die initialize-Instanz passen und könnten dort mehr Sinn ergeben. Gibt es einen bestimmten Weg: Initform wird in der Regel verwendet?

Antwort

4

Normalerweise würde man verwenden: initform, um einem Slot einen Standardwert zu geben. Mit Defclass kann man Initforms einfach nicht basierend auf anderen Slots berechnen. Es gibt auch andere Komplikationen, also: initform sollte für einfache Formen verwendet werden.

Beispiele

  • setzen die z Schlitz eines Objekts 3D-Vektor zu 0,0

  • die Liste der Fenster in einem Bildobjekt zu NIL

    gesetzt
  • setzen die ‚Schlüsselfunktion 'Platzieren Sie ein Objekt in #' Identität

  • Setzen Sie den 'Bericht String' Slot in einen Fehler auf "ein Fehler aufgetreten"

Jede andere kompliziertere Einrichtung von Slot-Werten sollte in einer Methode durchgeführt werden. Wenn das Objekt nach MAKE-INSTANCE automatisch eingerichtet werden soll, verwenden Sie eine: AFTER-Methode zu INITIALIZE-INSTANCE.

2

Um die Dinge ein wenig weiter zu komplizieren, gibt es auch die Klassenoption :default-initargs.

Ich persönlich verwende :default-initargs und :initform als Verknüpfungen, wenn die volle Leistung einer After-Methode für initialize-instance nicht benötigt wird, und :initform, wenn der Schlitz keine :initarg hat.