Ich habe einige grundlegende Fragen zu elisp.
Ich sehe oft so etwas
(search-forward "something" nil 'noerror)
Und manchmal sehe ich so etwas
(search-forward "something" nil :noerror)
Was ist der Unterschied und sollte ich eine Form der anderen vorziehen?
Soweit ich alles verstehe, wird die leere Liste in einem booleschen Kontext als wahr ausgewertet. Aber wie kommt das Folgende:
Wenn der Sucher "etwas" nicht im Puffer vorhanden ist, springt der Punkt zum Ende des Puffers, wenn 'noerror
er anstelle von verwendet wird t
. Bei t
Verwendung bleibt der Punkt dort, wo er ist.
Erster Fall:
(search-forward "something" nil 'noerror);; 1.Evaluate this
;; end of buffer 2.point jumps here
Zweiter Fall:
(search-forward "something" nil t);; 1.Evaluate this, 2. Point stays here
;; end of buffer
nil
von der angegebenen Funktion gleich behandelt werden, übergebe ich in meinem Code ein Symbol mit demselben Namen oder ähnlich dem in der Funktionsbeschreibung verwendeten Parameternamen und normalerweise in Großbuchstaben. Dies dient mir als Erinnerung, wenn ich den Code lese. ZB(search-forward "abc" nil 'NOERROR)
. Dies ist am hilfreichsten für optionale Argumente, die selten verwendet werden.Antworten:
Boolesche Werte in elisp funktionieren wie folgt:
nil
und()
(die, wie Sie beobachtet haben, dasselbe sind) sind falschDas
t
Symbol existiert als 'reiner' Wert von true (wenn die Verwendung eines anderen Werts keinen Vorteil bringt), aber die meisten Funktionen versuchen, etwas zurückzugeben, das ansonsten nützlich sein könnte, wann immer dies möglich ist.Siehe auch C-hig
(elisp) nil and t
RETWenn es darum geht, Schlüsselwortargumente oder andere Symbole als Nicht-
nil
Wert zu verwenden, wenn sich der Code nur umnil
oder Nicht- Wert kümmertnil
, ist dies wirklich nur eine Frage der persönlichen Präferenz. Es gibt keinen Unterschied in Bezug auf die Ausführung.Ich habe einmal dasselbe gefragt und wurde informiert, dass der Keyword-Argument-Ansatz eine allgemeinere Lisp-ish-Methode ist.
(Ich habe mich entschlossen, selbst Schlüsselwortargumente zu verwenden, teils zur Hervorhebung der Syntax, teils, weil sie dadurch besser von Variablen- und Funktionssymbolen unterschieden werden.)
In Bezug auf Ihrem spezifisches Beispiel die Funktion tut differenzierbare zwischen verschiedenem nicht -
nil
Wert und das Verhalten von seiner docstring bedeckt ist:Im Allgemeinen werden Sie feststellen, dass sich Docstrings eher auf "non-nil" als auf "true" oder "t" beziehen. Wenn Sie "t" sehen, besteht eine faire Chance, dass es sich um einen Sonderfall handelt.
quelle
nil
ist). Mit "rein" meine ich nur, dass es speziell existiert , um ein Wert zu sein, der "wahr" bedeutet, denn manchmal ist es das, was Sie wollen. Andere Nichtwertenil
sind jedoch immer noch genauso "wahr" wie siet
sind.Einige historische Hinweise sind fällig.
Emacs Lisp leiht viele Dinge von Common Lisp aus, aber die Ähnlichkeit ist nur oberflächentief. Das Doppelpunktsymbol in Common Lisp ist ein Namespace-Qualifikationsmerkmal. Kanonische Symbolnamen bestehen aus zwei Teilen: dem Namen des Pakets und dem Namen des Symbols in diesem Paket. Dies ist beispielsweise
cl-user:apropos
ein im Paket definiertes Symbolcl-user
. Es gibt auch ein spezielles Schlüsselwortpaket, das beim Start automatisch von Common Lisp importiert wird. Dieses Paket wird für die Kommunikation zwischen anderen Paketen verwendet (damit Pakete, die symbolische Informationen aneinander senden müssen, nicht darüber streiten, wer sie deklarieren muss). Wie Sie vielleicht erraten haben, werden Symbole in diesem Paket mit dem führenden Doppelpunkt geschrieben.Emacs Lisp hat kein Konzept für Pakete, aber der Doppelpunkt ist insofern etwas Besonderes, als er den Leser anweist, den Ausdruck als selbstbewertendes Symbol zu interpretieren (dh es handelt sich um eine Variable, deren Wert diese Variable selbst ist). Es gibt mehrere solche integrierte Selbst-Auswertung Symbole:
t
undnil
sind Beispiele , die ich über später schreiben werde.Das Apostroph stammt ebenfalls aus Common Lisp, wo es sich um ein Standardlesemakro handelt (dh um einen Code, den der Lisp-Interpreter beim Einlesen der Programmquelle ausführt). Es wird wie folgt erweitert:
'x -> (quote x)
Dabei(quote ...)
handelt es sich um eine spezielle Form, die den Lisp-Interpreter daran hindert, den Inhalt des Ausdrucks im Inneren auszuwerten. Emacs Lisp verfügt über drei integrierte Lesermakros :'
,`
und#
, aber Sie können keine eigenen hinzufügen. Die ersten beiden werden erweitert auf(quote ...)
, die zweite ermöglicht jedoch eine spezielle Syntax zum Erstellen des nicht bewerteten Ausdrucks.#
wird zu(function ...)
form erweitert , wodurch der Interpreter angewiesen wird, dass der Wert im Funktionsnamespace nachgeschlagen werden muss.Symbole in Emacs Lisp müssen einen bestimmten Wert haben (ähnlich wie Variablen in anderen Sprachen), da es sich sonst um einen Fehler handelt. Sie können die Bewertung jedoch mithilfe des Angebotsformulars verhindern.
Schließlich ist der Unterschied zwischen:
und
Haben Sie im ersten Fall
search-forward
mit einem Symbol ohne Wert aufgerufen , für das nur der Name bekannt ist, und im zweiten Fall haben Sie diese Funktion mit einem Symbol aufgerufen, dessen Wert dieses Symbol selbst ist. Es kommt also vor, dass es dieser Funktion egal ist, welche Sie verwenden.Typen sind ein wichtiges Programmierwerkzeug für die automatische Überprüfung von Programmen. Das Emacs Lisp-Typsystem ähnelt Common Lisp darin, dass sein universeller Typ (geschrieben als
t
) der Typ ist, von dem alle anderen Typen abgeleitet sind. Andererseitsnil
ist der Typ, von dem kein Typ abgeleitet ist (das Komplement vont
). Dies unterscheidet sich von vielen gängigen Programmiersprachen, die möglicherweise kein universelles Konzept oder einen bestimmten booleschen Typ haben.Leider hat Emacs Lisp diesen Teil leider nicht genau aus Common Lisp kopiert, und die
type-of
Funktion liefert verwirrende Ergebnisse fürt
undnil
.Emacs Lisp:
Common Lisp
Die Common Lisp-Erweiterung von Emacs Lisp hat eine Funktion,
cl-typep
die jedoch zum Verständnis der Beziehung beitragen kann. So zum Beispieldh was auch immer es
'noerror
ist, ist vom Typt
.quelle