setq-und defvar in Lisp
Sehe ich, dass die Practical Common Lisp verwendet (defvar *db* nil)
für die Einrichtung eines Globale variable. Ist es nicht OK zu verwenden setq
für den gleichen Zweck?
Was sind die Vorteile/Nachteile der Verwendung von defvar
vs. setq
?
InformationsquelleAutor der Frage prosseek | 2010-10-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es gibt mehrere Möglichkeiten zur Einführung von Variablen.
DEFVAR und DEFPARAMETER vorstellen globalen dynamische Variablen.
DEFVAR
Optional setzt Sie auf einen gewissen Wert, es sei denn, es ist bereits definiert.DEFPARAMETER
legt es immer auf die angegebenen Werte.SETQ nicht einführen einer Variablen.
Beachten Sie, dass Sie wahrscheinlich nie wollen, um
DEFVAR
Variablen mit Namen wiex
y
stream
limit
... Warum? Da diese Variablen dann wäre erklärt spezielle und schwer rückgängig zu machen. Die Besondere Erklärung ist global und alle weiteren Verwendungen der variable verwenden würden, dynamische Bindung.SCHLECHT:
BESSER: Immer daneben spezielle Variablen mit
*
in Ihrem Namen!Lokale Variablen eingeführt werden, mit DEFUNLAMBDALASSENMULTIPLE-VALUE-BIND und viele andere.
Nun standardmäßig die lokalen Variablen in den beiden oben genannten Formen, sind lexikalische, es sei denn, Sie deklariert sind BESONDERE. Dann wären Sie dynamische Variablen.
Nächsten, gibt es auch verschiedene Formen zum setzen einer Variablen auf neue Werte. SETSETQSETF und andere.
SETQ
undSETF
können sowohl lexikalische und spezielle (dynamische) Variablen.Es ist erforderlich für portablen code, setzt man Variablen sind bereits erklärt. Die genaue Wirkung der Einstellung eine nicht deklarierte variable ist nicht definiert durch die Norm.
Also, wenn Sie wissen, was Ihre Common-Lisp-Implementierung unterstützt, die Sie verwenden können,
in der Read-Eval-Print-Loop auf dem toplevel. Aber don ' T verwenden Sie es in Ihrem code, da die Wirkung ist nicht tragbar. In der Regel
SETQ
wird die variable setzen. Aber einige-Implementierung könnte auch erklären, die variable BESONDEREwenn er es nicht kennt (CMU Common Lisp macht das standardmäßig). Das ist fast immer nicht das, was man möchte. Verwenden Sie es für casual verwenden, wenn Sie wissen, was Sie tun, nicht aber für den code.Gleiche hier:
Ersten solche Variablen sollten so geschrieben werden, als
*world*
(mit den umliegenden*
Zeichen), um deutlich zu machen, dass es eine global special variable. Zweitens, es sollte erklärt wurden, mitDEFVAR
oderDEFPARAMETER
vor.Einem typischen Lisp-compiler wird sich beschweren, dass die oben genannten Variablen ist schwarzarbeit. Da Sie Globale lexikale Variablen nicht existieren in Common Lisp hat der compiler code generieren, eine dynamische Suche. Einige compiler dann sagen, okay, wir gehen davon aus, dass dies eine dynamische Suche, lassen Sie uns erklären, um sein Besondere - denn das ist, was wir vermuten sowieso.
InformationsquelleAutor der Antwort Rainer Joswig
defvar
stellt eine dynamische variable, währendsetq
wird verwendet, um einen Wert zuweisen, um eine dynamische oder eine lexikalische variable an. Der Wert einer dynamischen Variablen blickte in die Umgebung, der die Funktion aufruft, während der Wert der eine lexikalische variable ist, blickte in die Umgebung, wo die Funktion definiert wurde. Das folgende Beispiel macht den Unterschied klar:Dynamischen Variablen sind nützlich für die Weitergabe um einen default-Wert. Wir können zum Beispiel binden die dynamische variable
*out*
auf die standard-Ausgabe, so dass es wird die Standard-Ausgabe der io-Funktionen. Um dieses Verhalten außer Kraft setzen, wir nur die Einführung einer lokalen Bindung:Einer gemeinsamen Nutzung von lexikalischen Variablen ist bei der Festlegung Verschlüsse nachzueifern, um Objekte mit Zustand. Im ersten Beispiel wird die variable
y
in der Bindung-Umgebung vonfy
effektiv wurde der private Status der Funktion.defvar
zuweisen eines Wertes an eine variable nur dann, wenn es nicht bereits zugewiesen ist. Also Folgendes re-definition von*x*
wird sich nicht ändern, die ursprüngliche Bindung:Wir können einen neuen Wert zuweisen, um
*x*
mithilfesetq
:InformationsquelleAutor der Antwort Vijay Mathew
DEFVAR wird eine neue variable. SETQ weist einer Variablen.
Meisten Lisp-Implementierungen, die ich verwendet habe, wird eine Warnung auszugeben, wenn Sie SETQ auf eine variable, die noch nicht existiert.
InformationsquelleAutor der Antwort Ken
defvar
unddefparameter
beide vor globalen Variablen. Als Ken Notizensetq
weist einer Variablen.Darüber hinaus
defvar
wird nicht clobber etwas zuvordefvar
-ed. Seibel sagt später im Buch (Kapitel 6): "Praktisch gesprochen, die Sie verwenden sollten, DEFVAR, Variablen zu definieren, die Daten enthalten, die Sie wollen, zu halten, selbst wenn Sie eine änderung in der source-code, der Variablen verwendet, die."http://www.gigamonkeys.com/book/variables.html
Zum Beispiel, wenn Sie eine Globale
*db*
für die Datenbank in der Einfachen Datenbank-Kapitel:...und Sie anfangen zu spielen mit ihm an der REPL - hinzufügen, löschen, usw - aber dann machen Sie eine änderung der source-Datei, die enthält, dass defvar form, nachladen, dass die Datei nicht auszulöschen
*db*
und alle änderungen, die Sie gemacht haben könnte... ich glaube, dasssetq
wird, so wirddefparameter
. Ein erfahrener Lisper bitte korrigieren Sie mich, wenn ich falsch bin, aber.InformationsquelleAutor der Antwort michiakig